Compare commits
100 Commits
1400_suppo
...
1.3.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e96972c939 | ||
|
|
3545c0aac2 | ||
|
|
d85875b910 | ||
|
|
b1367942a2 | ||
|
|
c2c0a2e169 | ||
|
|
f5052b4bca | ||
|
|
70d67bb115 | ||
|
|
9056e0b05f | ||
|
|
895b6d0470 | ||
|
|
dfba595cdc | ||
|
|
175a34da43 | ||
|
|
02b126c2be | ||
|
|
b45671fd35 | ||
|
|
106599895d | ||
|
|
80154b0a54 | ||
|
|
62eb4d6989 | ||
|
|
b52e44e798 | ||
|
|
72baa4ff18 | ||
|
|
442656899f | ||
|
|
d7f89a0c31 | ||
|
|
2e6223d9d0 | ||
|
|
28f11a86fd | ||
|
|
a8b52dc123 | ||
|
|
9b47ddf01f | ||
|
|
0fbf007bcf | ||
|
|
4ad8dad416 | ||
|
|
8e258bde9d | ||
|
|
c0d5140ef0 | ||
|
|
1bef1b58d4 | ||
|
|
07cd682460 | ||
|
|
e5c3d264ec | ||
|
|
bbf22b4c60 | ||
|
|
dd78ede99f | ||
|
|
e5b1739f65 | ||
|
|
a4a2cc2218 | ||
|
|
5ffbed1bee | ||
|
|
ec44eaa263 | ||
|
|
20e53fcd82 | ||
|
|
64c6ef2de7 | ||
|
|
817ad8f98d | ||
|
|
dfa475a769 | ||
|
|
141ae5c7ab | ||
|
|
4646581e93 | ||
|
|
b69fa13576 | ||
|
|
0da15a30fd | ||
|
|
44d553d12e | ||
|
|
6f54ab5716 | ||
|
|
596a0f2551 | ||
|
|
ff828dc0bc | ||
|
|
027f3b4911 | ||
|
|
3fff114b14 | ||
|
|
f23f490cb4 | ||
|
|
c503629ac8 | ||
|
|
6b436739be | ||
|
|
4f763b2aa4 | ||
|
|
12d83106fd | ||
|
|
e3cb5e74b9 | ||
|
|
b1a4a0db67 | ||
|
|
847fee4901 | ||
|
|
f2b48d466f | ||
|
|
6e97dff27f | ||
|
|
be399772c0 | ||
|
|
45da60f902 | ||
|
|
01fd324d4f | ||
|
|
f95bdb87a0 | ||
|
|
91d3d242f5 | ||
|
|
383fc2cc99 | ||
|
|
1ca2f61527 | ||
|
|
cdc619a8a6 | ||
|
|
ff07ba4201 | ||
|
|
9d89835ff8 | ||
|
|
6e17317d5d | ||
|
|
79afa3b64c | ||
|
|
f3968f5f7c | ||
|
|
a8e23adffe | ||
|
|
401047f603 | ||
|
|
24739f245e | ||
|
|
8cb3cfd835 | ||
|
|
14e768cd10 | ||
|
|
ef1b67b87b | ||
|
|
8ef6c49d30 | ||
|
|
a89c5dd5d7 | ||
|
|
dfcb5005d2 | ||
|
|
f3e3649bd5 | ||
|
|
07f91f0a83 | ||
|
|
81005fa3f8 | ||
|
|
60d78bbf75 | ||
|
|
247852db3a | ||
|
|
51c145f6c9 | ||
|
|
74fddf667a | ||
|
|
027242e909 | ||
|
|
86f98e49c7 | ||
|
|
3579797309 | ||
|
|
77b3bfcd16 | ||
|
|
fa98bf9434 | ||
|
|
e975784179 | ||
|
|
dc643daaa7 | ||
|
|
e05df99342 | ||
|
|
0cfc93d423 | ||
|
|
588d761615 |
@@ -1,4 +1,17 @@
|
|||||||
# Changelog
|
# 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
|
## 1.3.0
|
||||||
+ Support was added for 14.0.0.
|
+ Support was added for 14.0.0.
|
||||||
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||||
@@ -15,9 +28,10 @@
|
|||||||
+ If you are a developer interested in adding support for another target, please reach out to `SciresM#0524` on discord.
|
+ 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.
|
+ 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..
|
+ 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 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.
|
+ **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 major revisions were added to stratosphere:
|
+ 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.
|
||||||
+ General system stability improvements to enhance the user's experience.
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 1.2.6
|
## 1.2.6
|
||||||
+ Support was added for 13.2.1.
|
+ 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
|
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||||
;
|
;
|
||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emuMMC
|
remote = https://github.com/m4xw/emummc
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = a9d56959460fc794ce2cb6405402c25a3e89c47f
|
commit = 56a2e8a2078944d9bf8daead237036254bb6e36d
|
||||||
parent = ff719641396c635b735873fb2b020c910f768a04
|
parent = 4f763b2aa401ac3e3d699ec8c866ae9b3c8fb28d
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
28
emummc/source/nx/cache.s
vendored
28
emummc/source/nx/cache.s
vendored
@@ -27,6 +27,10 @@ CODE_BEGIN armDCacheFlush
|
|||||||
bic x8, x0, x10
|
bic x8, x0, x10
|
||||||
mov x10, x1
|
mov x10, x1
|
||||||
|
|
||||||
|
mov w1, #1
|
||||||
|
mrs x0, tpidrro_el0
|
||||||
|
strb w1, [x0, #0x104]
|
||||||
|
|
||||||
armDCacheFlush_L0:
|
armDCacheFlush_L0:
|
||||||
dc civac, x8
|
dc civac, x8
|
||||||
add x8, x8, x9
|
add x8, x8, x9
|
||||||
@@ -34,6 +38,9 @@ armDCacheFlush_L0:
|
|||||||
bcc armDCacheFlush_L0
|
bcc armDCacheFlush_L0
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
|
|
||||||
|
strb wzr, [x0, #0x104]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
CODE_END
|
CODE_END
|
||||||
|
|
||||||
@@ -48,6 +55,10 @@ CODE_BEGIN armDCacheClean
|
|||||||
bic x8, x0, x10
|
bic x8, x0, x10
|
||||||
mov x10, x1
|
mov x10, x1
|
||||||
|
|
||||||
|
mov w1, #1
|
||||||
|
mrs x0, tpidrro_el0
|
||||||
|
strb w1, [x0, #0x104]
|
||||||
|
|
||||||
armDCacheClean_L0:
|
armDCacheClean_L0:
|
||||||
dc cvac, x8
|
dc cvac, x8
|
||||||
add x8, x8, x9
|
add x8, x8, x9
|
||||||
@@ -55,6 +66,9 @@ armDCacheClean_L0:
|
|||||||
bcc armDCacheClean_L0
|
bcc armDCacheClean_L0
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
|
|
||||||
|
strb wzr, [x0, #0x104]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
CODE_END
|
CODE_END
|
||||||
|
|
||||||
@@ -68,6 +82,10 @@ CODE_BEGIN armICacheInvalidate
|
|||||||
bic x8, x0, x10
|
bic x8, x0, x10
|
||||||
mov x10, x1
|
mov x10, x1
|
||||||
|
|
||||||
|
mov w1, #1
|
||||||
|
mrs x0, tpidrro_el0
|
||||||
|
strb w1, [x0, #0x104]
|
||||||
|
|
||||||
armICacheInvalidate_L0:
|
armICacheInvalidate_L0:
|
||||||
ic ivau, x8
|
ic ivau, x8
|
||||||
add x8, x8, x9
|
add x8, x8, x9
|
||||||
@@ -75,6 +93,9 @@ armICacheInvalidate_L0:
|
|||||||
bcc armICacheInvalidate_L0
|
bcc armICacheInvalidate_L0
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
|
|
||||||
|
strb wzr, [x0, #0x104]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
CODE_END
|
CODE_END
|
||||||
|
|
||||||
@@ -89,6 +110,10 @@ CODE_BEGIN armDCacheZero
|
|||||||
bic x8, x0, x10
|
bic x8, x0, x10
|
||||||
mov x10, x1
|
mov x10, x1
|
||||||
|
|
||||||
|
mov w1, #1
|
||||||
|
mrs x0, tpidrro_el0
|
||||||
|
strb w1, [x0, #0x104]
|
||||||
|
|
||||||
armDCacheZero_L0:
|
armDCacheZero_L0:
|
||||||
dc zva, x8
|
dc zva, x8
|
||||||
add x8, x8, x9
|
add x8, x8, x9
|
||||||
@@ -96,5 +121,8 @@ armDCacheZero_L0:
|
|||||||
bcc armDCacheZero_L0
|
bcc armDCacheZero_L0
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
|
|
||||||
|
strb wzr, [x0, #0x104]
|
||||||
|
|
||||||
ret
|
ret
|
||||||
CODE_END
|
CODE_END
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace ams::secmon::fatal {
|
|||||||
/* Write the context to the file. */
|
/* Write the context to the file. */
|
||||||
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
|
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ namespace ams::secmon::fatal {
|
|||||||
//sdmmc::Deactivate(Port);
|
//sdmmc::Deactivate(Port);
|
||||||
R_TRY(sdmmc::Activate(Port));
|
R_TRY(sdmmc::Activate(Port));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||||
return sdmmc::CheckSdCardConnection(out_sm, out_bw, Port);
|
R_RETURN(sdmmc::CheckSdCardConnection(out_sm, out_bw, Port));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
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;
|
sector_count -= cur_sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
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;
|
sector_count -= cur_sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,45 +34,45 @@ namespace ams::fs {
|
|||||||
Result TranslateFatFsError(FRESULT res) {
|
Result TranslateFatFsError(FRESULT res) {
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
case FR_DISK_ERR:
|
case FR_DISK_ERR:
|
||||||
return fs::ResultMmcAccessFailed();
|
R_THROW(fs::ResultMmcAccessFailed());
|
||||||
case FR_INT_ERR:
|
case FR_INT_ERR:
|
||||||
return fs::ResultPreconditionViolation();
|
R_THROW(fs::ResultPreconditionViolation());
|
||||||
case FR_NOT_READY:
|
case FR_NOT_READY:
|
||||||
return fs::ResultMmcAccessFailed();
|
R_THROW(fs::ResultMmcAccessFailed());
|
||||||
case FR_NO_FILE:
|
case FR_NO_FILE:
|
||||||
return fs::ResultPathNotFound();
|
R_THROW(fs::ResultPathNotFound());
|
||||||
case FR_NO_PATH:
|
case FR_NO_PATH:
|
||||||
return fs::ResultPathNotFound();
|
R_THROW(fs::ResultPathNotFound());
|
||||||
case FR_INVALID_NAME:
|
case FR_INVALID_NAME:
|
||||||
return fs::ResultInvalidPath();
|
R_THROW(fs::ResultInvalidPath());
|
||||||
case FR_DENIED:
|
case FR_DENIED:
|
||||||
return fs::ResultPermissionDenied();
|
R_THROW(fs::ResultPermissionDenied());
|
||||||
case FR_EXIST:
|
case FR_EXIST:
|
||||||
return fs::ResultPathAlreadyExists();
|
R_THROW(fs::ResultPathAlreadyExists());
|
||||||
case FR_INVALID_OBJECT:
|
case FR_INVALID_OBJECT:
|
||||||
return fs::ResultInvalidArgument();
|
R_THROW(fs::ResultInvalidArgument());
|
||||||
case FR_WRITE_PROTECTED:
|
case FR_WRITE_PROTECTED:
|
||||||
return fs::ResultWriteNotPermitted();
|
R_THROW(fs::ResultWriteNotPermitted());
|
||||||
case FR_INVALID_DRIVE:
|
case FR_INVALID_DRIVE:
|
||||||
return fs::ResultInvalidMountName();
|
R_THROW(fs::ResultInvalidMountName());
|
||||||
case FR_NOT_ENABLED:
|
case FR_NOT_ENABLED:
|
||||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||||
case FR_NO_FILESYSTEM:
|
case FR_NO_FILESYSTEM:
|
||||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||||
case FR_TIMEOUT:
|
case FR_TIMEOUT:
|
||||||
return fs::ResultTargetLocked(); /* BAD/TODO */
|
R_THROW(fs::ResultTargetLocked()); /* BAD/TODO */
|
||||||
case FR_LOCKED:
|
case FR_LOCKED:
|
||||||
return fs::ResultTargetLocked();
|
R_THROW(fs::ResultTargetLocked());
|
||||||
case FR_NOT_ENOUGH_CORE:
|
case FR_NOT_ENOUGH_CORE:
|
||||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||||
case FR_TOO_MANY_OPEN_FILES:
|
case FR_TOO_MANY_OPEN_FILES:
|
||||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||||
case FR_INVALID_PARAMETER:
|
case FR_INVALID_PARAMETER:
|
||||||
return fs::ResultInvalidArgument();
|
R_THROW(fs::ResultInvalidArgument());
|
||||||
default:
|
default:
|
||||||
return fs::ResultInternal();
|
R_THROW(fs::ResultInternal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,11 +125,11 @@ namespace ams::fs {
|
|||||||
/* Expand the file. */
|
/* Expand the file. */
|
||||||
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
|
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectory(const char *path) {
|
Result CreateDirectory(const char *path) {
|
||||||
return TranslateFatFsError(f_mkdir(path));
|
R_RETURN(TranslateFatFsError(f_mkdir(path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
||||||
@@ -144,10 +144,10 @@ namespace ams::fs {
|
|||||||
out_file->_handle = fp;
|
out_file->_handle = fp;
|
||||||
g_files_opened[i] = true;
|
g_files_opened[i] = true;
|
||||||
g_open_modes[i] = mode;
|
g_open_modes[i] = mode;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fs::ResultOpenCountLimit();
|
R_THROW(fs::ResultOpenCountLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
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. */
|
/* Check that we read the correct amount. */
|
||||||
R_UNLESS(br == size, fs::ResultOutOfRange());
|
R_UNLESS(br == size, fs::ResultOutOfRange());
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||||
return ReadFile(handle, offset, buffer, size, fs::ReadOption::None);
|
R_RETURN(ReadFile(handle, offset, buffer, size, fs::ReadOption::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
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. */
|
/* Set the output size. */
|
||||||
*out = br;
|
*out = br;
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||||
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
|
R_RETURN(ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||||
FIL *fp = GetInternalFile(handle);
|
FIL *fp = GetInternalFile(handle);
|
||||||
*out = f_size(fp);
|
*out = f_size(fp);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FlushFile(FileHandle handle) {
|
Result FlushFile(FileHandle handle) {
|
||||||
return TranslateFatFsError(f_sync(GetInternalFile(handle)));
|
R_RETURN(TranslateFatFsError(f_sync(GetInternalFile(handle))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
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_TRY(FlushFile(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetFileSize(FileHandle handle, s64 size) {
|
Result SetFileSize(FileHandle handle, s64 size) {
|
||||||
@@ -242,7 +242,7 @@ namespace ams::fs {
|
|||||||
/* Check that our expansion succeeded. */
|
/* Check that our expansion succeeded. */
|
||||||
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
|
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFileOpenMode(FileHandle handle) {
|
int GetFileOpenMode(FileHandle handle) {
|
||||||
|
|||||||
@@ -39,45 +39,45 @@ namespace ams::fs {
|
|||||||
Result TranslateFatFsError(FRESULT res) {
|
Result TranslateFatFsError(FRESULT res) {
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
case FR_DISK_ERR:
|
case FR_DISK_ERR:
|
||||||
return fs::ResultMmcAccessFailed();
|
R_THROW(fs::ResultMmcAccessFailed());
|
||||||
case FR_INT_ERR:
|
case FR_INT_ERR:
|
||||||
return fs::ResultPreconditionViolation();
|
R_THROW(fs::ResultPreconditionViolation());
|
||||||
case FR_NOT_READY:
|
case FR_NOT_READY:
|
||||||
return fs::ResultMmcAccessFailed();
|
R_THROW(fs::ResultMmcAccessFailed());
|
||||||
case FR_NO_FILE:
|
case FR_NO_FILE:
|
||||||
return fs::ResultPathNotFound();
|
R_THROW(fs::ResultPathNotFound());
|
||||||
case FR_NO_PATH:
|
case FR_NO_PATH:
|
||||||
return fs::ResultPathNotFound();
|
R_THROW(fs::ResultPathNotFound());
|
||||||
case FR_INVALID_NAME:
|
case FR_INVALID_NAME:
|
||||||
return fs::ResultInvalidPath();
|
R_THROW(fs::ResultInvalidPath());
|
||||||
case FR_DENIED:
|
case FR_DENIED:
|
||||||
return fs::ResultPermissionDenied();
|
R_THROW(fs::ResultPermissionDenied());
|
||||||
case FR_EXIST:
|
case FR_EXIST:
|
||||||
return fs::ResultPathAlreadyExists();
|
R_THROW(fs::ResultPathAlreadyExists());
|
||||||
case FR_INVALID_OBJECT:
|
case FR_INVALID_OBJECT:
|
||||||
return fs::ResultInvalidArgument();
|
R_THROW(fs::ResultInvalidArgument());
|
||||||
case FR_WRITE_PROTECTED:
|
case FR_WRITE_PROTECTED:
|
||||||
return fs::ResultWriteNotPermitted();
|
R_THROW(fs::ResultWriteNotPermitted());
|
||||||
case FR_INVALID_DRIVE:
|
case FR_INVALID_DRIVE:
|
||||||
return fs::ResultInvalidMountName();
|
R_THROW(fs::ResultInvalidMountName());
|
||||||
case FR_NOT_ENABLED:
|
case FR_NOT_ENABLED:
|
||||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||||
case FR_NO_FILESYSTEM:
|
case FR_NO_FILESYSTEM:
|
||||||
return fs::ResultInvalidMountName(); /* BAD/TODO */
|
R_THROW(fs::ResultInvalidMountName()); /* BAD/TODO */
|
||||||
case FR_TIMEOUT:
|
case FR_TIMEOUT:
|
||||||
return fs::ResultTargetLocked(); /* BAD/TODO */
|
R_THROW(fs::ResultTargetLocked()); /* BAD/TODO */
|
||||||
case FR_LOCKED:
|
case FR_LOCKED:
|
||||||
return fs::ResultTargetLocked();
|
R_THROW(fs::ResultTargetLocked());
|
||||||
case FR_NOT_ENOUGH_CORE:
|
case FR_NOT_ENOUGH_CORE:
|
||||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||||
case FR_TOO_MANY_OPEN_FILES:
|
case FR_TOO_MANY_OPEN_FILES:
|
||||||
return fs::ResultPreconditionViolation(); /* BAD/TODO */
|
R_THROW(fs::ResultPreconditionViolation()); /* BAD/TODO */
|
||||||
case FR_INVALID_PARAMETER:
|
case FR_INVALID_PARAMETER:
|
||||||
return fs::ResultInvalidArgument();
|
R_THROW(fs::ResultInvalidArgument());
|
||||||
default:
|
default:
|
||||||
return fs::ResultInternal();
|
R_THROW(fs::ResultInternal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ namespace ams::fs {
|
|||||||
*out_entry_type = (info.fattrib & AM_DIR) ? DirectoryEntryType_Directory : DirectoryEntryType_File;
|
*out_entry_type = (info.fattrib & AM_DIR) ? DirectoryEntryType_Directory : DirectoryEntryType_File;
|
||||||
*out_archive = (info.fattrib & AM_ARC);
|
*out_archive = (info.fattrib & AM_ARC);
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateFile(const char *path, s64 size) {
|
Result CreateFile(const char *path, s64 size) {
|
||||||
@@ -152,11 +152,11 @@ namespace ams::fs {
|
|||||||
/* Expand the file. */
|
/* Expand the file. */
|
||||||
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
|
R_TRY(TranslateFatFsError(f_expand(std::addressof(fp), size, 1)));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectory(const char *path) {
|
Result CreateDirectory(const char *path) {
|
||||||
return TranslateFatFsError(f_mkdir(path));
|
R_RETURN(TranslateFatFsError(f_mkdir(path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
Result OpenFile(FileHandle *out_file, const char *path, int mode) {
|
||||||
@@ -171,10 +171,10 @@ namespace ams::fs {
|
|||||||
out_file->_handle = fp;
|
out_file->_handle = fp;
|
||||||
g_files_opened[i] = true;
|
g_files_opened[i] = true;
|
||||||
g_open_modes[i] = mode;
|
g_open_modes[i] = mode;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fs::ResultOpenCountLimit();
|
R_THROW(fs::ResultOpenCountLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenDirectory(DirectoryHandle *out_dir, const char *path) {
|
Result OpenDirectory(DirectoryHandle *out_dir, const char *path) {
|
||||||
@@ -188,10 +188,10 @@ namespace ams::fs {
|
|||||||
/* Set the output. */
|
/* Set the output. */
|
||||||
out_dir->_handle = dp;
|
out_dir->_handle = dp;
|
||||||
g_dirs_opened[i] = true;
|
g_dirs_opened[i] = true;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fs::ResultOpenCountLimit();
|
R_THROW(fs::ResultOpenCountLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
|
Result ReadDirectory(s64 *out_count, DirectoryEntry *out_entries, DirectoryHandle handle, s64 max_entries) {
|
||||||
@@ -209,7 +209,7 @@ namespace ams::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*out_count = count;
|
*out_count = count;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseDirectory(DirectoryHandle handle) {
|
void CloseDirectory(DirectoryHandle handle) {
|
||||||
@@ -232,11 +232,11 @@ namespace ams::fs {
|
|||||||
/* Check that we read the correct amount. */
|
/* Check that we read the correct amount. */
|
||||||
R_UNLESS(br == size, fs::ResultOutOfRange());
|
R_UNLESS(br == size, fs::ResultOutOfRange());
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||||
return ReadFile(handle, offset, buffer, size, fs::ReadOption::None);
|
R_RETURN(ReadFile(handle, offset, buffer, size, fs::ReadOption::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
|
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. */
|
/* Set the output size. */
|
||||||
*out = br;
|
*out = br;
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
|
||||||
return ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None);
|
R_RETURN(ReadFile(out, handle, offset, buffer, size, fs::ReadOption::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetFileSize(s64 *out, FileHandle handle) {
|
Result GetFileSize(s64 *out, FileHandle handle) {
|
||||||
FIL *fp = GetInternalFile(handle);
|
FIL *fp = GetInternalFile(handle);
|
||||||
*out = f_size(fp);
|
*out = f_size(fp);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FlushFile(FileHandle handle) {
|
Result FlushFile(FileHandle handle) {
|
||||||
return TranslateFatFsError(f_sync(GetInternalFile(handle)));
|
R_RETURN(TranslateFatFsError(f_sync(GetInternalFile(handle))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
|
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_TRY(FlushFile(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetFileSize(FileHandle handle, s64 size) {
|
Result SetFileSize(FileHandle handle, s64 size) {
|
||||||
@@ -310,7 +310,7 @@ namespace ams::fs {
|
|||||||
/* Check that our expansion succeeded. */
|
/* Check that our expansion succeeded. */
|
||||||
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
|
AMS_ASSERT(f_size(fp) == static_cast<FSIZE_t>(size));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFileOpenMode(FileHandle handle) {
|
int GetFileOpenMode(FileHandle handle) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace ams::fs {
|
|||||||
|
|
||||||
Result FileHandleStorage::UpdateSize() {
|
Result FileHandleStorage::UpdateSize() {
|
||||||
R_SUCCEED_IF(m_size != InvalidSize);
|
R_SUCCEED_IF(m_size != InvalidSize);
|
||||||
return GetFileSize(std::addressof(m_size), m_handle);
|
R_RETURN(GetFileSize(std::addressof(m_size), m_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileHandleStorage::Read(s64 offset, void *buffer, size_t size) {
|
Result FileHandleStorage::Read(s64 offset, void *buffer, size_t size) {
|
||||||
@@ -34,9 +34,9 @@ namespace ams::fs {
|
|||||||
R_TRY(this->UpdateSize());
|
R_TRY(this->UpdateSize());
|
||||||
|
|
||||||
/* Ensure our access is valid. */
|
/* Ensure our access is valid. */
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
|
|
||||||
return ReadFile(m_handle, offset, buffer, size, fs::ReadOption());
|
R_RETURN(ReadFile(m_handle, offset, buffer, size, fs::ReadOption()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileHandleStorage::Write(s64 offset, const void *buffer, size_t size) {
|
Result FileHandleStorage::Write(s64 offset, const void *buffer, size_t size) {
|
||||||
@@ -50,24 +50,24 @@ namespace ams::fs {
|
|||||||
R_TRY(this->UpdateSize());
|
R_TRY(this->UpdateSize());
|
||||||
|
|
||||||
/* Ensure our access is valid. */
|
/* Ensure our access is valid. */
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
|
|
||||||
return WriteFile(m_handle, offset, buffer, size, fs::WriteOption());
|
R_RETURN(WriteFile(m_handle, offset, buffer, size, fs::WriteOption()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileHandleStorage::Flush() {
|
Result FileHandleStorage::Flush() {
|
||||||
return FlushFile(m_handle);
|
R_RETURN(FlushFile(m_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileHandleStorage::GetSize(s64 *out_size) {
|
Result FileHandleStorage::GetSize(s64 *out_size) {
|
||||||
R_TRY(this->UpdateSize());
|
R_TRY(this->UpdateSize());
|
||||||
*out_size = m_size;
|
*out_size = m_size;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileHandleStorage::SetSize(s64 size) {
|
Result FileHandleStorage::SetSize(s64 size) {
|
||||||
m_size = InvalidSize;
|
m_size = InvalidSize;
|
||||||
return SetFileSize(m_handle, size);
|
R_RETURN(SetFileSize(m_handle, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,25 +31,38 @@ namespace ams::fs {
|
|||||||
|
|
||||||
virtual Result GetSize(s64 *out) = 0;
|
virtual Result GetSize(s64 *out) = 0;
|
||||||
public:
|
public:
|
||||||
static inline bool CheckAccessRange(s64 offset, s64 size, s64 total_size) {
|
static inline Result CheckAccessRange(s64 offset, s64 size, s64 total_size) {
|
||||||
return offset >= 0 &&
|
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||||
size >= 0 &&
|
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||||
size <= total_size &&
|
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||||
offset <= (total_size - size);
|
R_UNLESS(offset + size <= total_size, fs::ResultOutOfRange());
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
static ALWAYS_INLINE Result CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
||||||
return CheckAccessRange(offset, static_cast<s64>(size), total_size);
|
R_RETURN(CheckAccessRange(offset, static_cast<s64>(size), total_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CheckOffsetAndSize(s64 offset, s64 size) {
|
static inline Result CheckOffsetAndSize(s64 offset, s64 size) {
|
||||||
return offset >= 0 &&
|
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||||
size >= 0 &&
|
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||||
offset <= (offset + size);
|
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
|
static ALWAYS_INLINE Result CheckOffsetAndSize(s64 offset, size_t size) {
|
||||||
return CheckOffsetAndSize(offset, static_cast<s64>(size));
|
R_RETURN(CheckOffsetAndSize(offset, static_cast<s64>(size)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Result CheckOffsetAndSizeWithResult(s64 offset, s64 size, Result fail_result) {
|
||||||
|
R_TRY_CATCH(CheckOffsetAndSize(offset, size)) {
|
||||||
|
R_CONVERT_ALL(fail_result);
|
||||||
|
} R_END_TRY_CATCH;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE Result CheckOffsetAndSizeWithResult(s64 offset, size_t size, Result fail_result) {
|
||||||
|
R_RETURN(CheckOffsetAndSizeWithResult(offset, static_cast<s64>(size), fail_result));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,23 +73,23 @@ namespace ams::fs {
|
|||||||
ReadOnlyStorageAdapter(IStorage &s) : m_storage(s) { /* ... */ }
|
ReadOnlyStorageAdapter(IStorage &s) : m_storage(s) { /* ... */ }
|
||||||
|
|
||||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||||
return m_storage.Read(offset, buffer, size);
|
R_RETURN(m_storage.Read(offset, buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return m_storage.Flush();
|
R_RETURN(m_storage.Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
return m_storage.GetSize(out);
|
R_RETURN(m_storage.GetSize(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,9 +106,9 @@ namespace ams::fs {
|
|||||||
R_SUCCEED_IF(size == 0);
|
R_SUCCEED_IF(size == 0);
|
||||||
|
|
||||||
/* Validate arguments and read. */
|
/* Validate arguments and read. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
return m_storage.Read(m_offset + offset, buffer, size);
|
R_RETURN(m_storage.Read(m_offset + offset, buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
||||||
@@ -103,22 +116,22 @@ namespace ams::fs {
|
|||||||
R_SUCCEED_IF(size == 0);
|
R_SUCCEED_IF(size == 0);
|
||||||
|
|
||||||
/* Validate arguments and write. */
|
/* Validate arguments and write. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
return m_storage.Write(m_offset + offset, buffer, size);
|
R_RETURN(m_storage.Write(m_offset + offset, buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return m_storage.Flush();
|
R_RETURN(m_storage.Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
*out = m_size;
|
*out = m_size;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
return fs::ResultUnsupportedSetSizeForNotResizableSubStorage();
|
R_THROW(fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ namespace ams::nxboot {
|
|||||||
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
|
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
|
R_RETURN(ReadSdCard(buffer, size, offset / sdmmc::SectorSize, size / sdmmc::SectorSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
@@ -45,15 +45,15 @@ namespace ams::nxboot {
|
|||||||
R_TRY(GetSdCardMemoryCapacity(std::addressof(num_sectors)));
|
R_TRY(GetSdCardMemoryCapacity(std::addressof(num_sectors)));
|
||||||
|
|
||||||
*out = static_cast<s64>(num_sectors) * static_cast<s64>(sdmmc::SectorSize);
|
*out = static_cast<s64>(num_sectors) * static_cast<s64>(sdmmc::SectorSize);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,11 +67,11 @@ namespace ams::nxboot {
|
|||||||
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
|
ShowFatalError("SdCard: unaligned access to %" PRIx64 ", size=%" PRIx64"\n", static_cast<u64>(offset), static_cast<u64>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize);
|
R_RETURN(ReadMmc(buffer, size, Partition, offset / sdmmc::SectorSize, size / sdmmc::SectorSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
@@ -79,15 +79,15 @@ namespace ams::nxboot {
|
|||||||
R_TRY(GetMmcMemoryCapacity(std::addressof(num_sectors), Partition));
|
R_TRY(GetMmcMemoryCapacity(std::addressof(num_sectors), Partition));
|
||||||
|
|
||||||
*out = num_sectors * sdmmc::SectorSize;
|
*out = num_sectors * sdmmc::SectorSize;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,23 +153,23 @@ namespace ams::nxboot {
|
|||||||
subofs = 0;
|
subofs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -349,11 +349,11 @@ namespace ams::nxboot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ReadBoot0(s64 offset, void *dst, size_t size) {
|
Result ReadBoot0(s64 offset, void *dst, size_t size) {
|
||||||
return g_boot0_storage->Read(offset, dst, size);
|
R_RETURN(g_boot0_storage->Read(offset, dst, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadPackage2(s64 offset, void *dst, size_t size) {
|
Result ReadPackage2(s64 offset, void *dst, size_t size) {
|
||||||
return g_package2_storage->Read(offset, dst, size);
|
R_RETURN(g_package2_storage->Read(offset, dst, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace ams::nxboot {
|
|||||||
/* Write the context to the file. */
|
/* Write the context to the file. */
|
||||||
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
|
R_TRY(fs::WriteFile(file, 0, ctx, sizeof(*ctx), fs::WriteOption::Flush));
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace ams::nxboot {
|
|||||||
g_mmc_partition = partition;
|
g_mmc_partition = partition;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -47,29 +47,29 @@ namespace ams::nxboot {
|
|||||||
sdmmc::SetMmcWorkBuffer(MmcPort, g_mmc_work_buffer, sizeof(g_mmc_work_buffer));
|
sdmmc::SetMmcWorkBuffer(MmcPort, g_mmc_work_buffer, sizeof(g_mmc_work_buffer));
|
||||||
|
|
||||||
/* Activate the mmc. */
|
/* Activate the mmc. */
|
||||||
return sdmmc::Activate(MmcPort);
|
R_RETURN(sdmmc::Activate(MmcPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheckMmcConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
Result CheckMmcConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||||
return sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort);
|
R_RETURN(sdmmc::CheckMmcConnection(out_sm, out_bw, MmcPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetMmcMemoryCapacity(u32 *out_num_sectors, sdmmc::MmcPartition partition) {
|
Result GetMmcMemoryCapacity(u32 *out_num_sectors, sdmmc::MmcPartition partition) {
|
||||||
if (partition == sdmmc::MmcPartition_UserData) {
|
if (partition == sdmmc::MmcPartition_UserData) {
|
||||||
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort);
|
R_RETURN(sdmmc::GetDeviceMemoryCapacity(out_num_sectors, MmcPort));
|
||||||
} else {
|
} else {
|
||||||
return sdmmc::GetMmcBootPartitionCapacity(out_num_sectors, MmcPort);
|
R_RETURN(sdmmc::GetMmcBootPartitionCapacity(out_num_sectors, MmcPort));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadMmc(void *dst, size_t size, sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count) {
|
Result ReadMmc(void *dst, size_t size, sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count) {
|
||||||
R_TRY(SelectMmcPartition(partition));
|
R_TRY(SelectMmcPartition(partition));
|
||||||
return sdmmc::Read(dst, size, MmcPort, sector_index, sector_count);
|
R_RETURN(sdmmc::Read(dst, size, MmcPort, sector_index, sector_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteMmc(sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
Result WriteMmc(sdmmc::MmcPartition partition, size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||||
R_TRY(SelectMmcPartition(partition));
|
R_TRY(SelectMmcPartition(partition));
|
||||||
return sdmmc::Write(MmcPort, sector_index, sector_count, src, size);
|
R_RETURN(sdmmc::Write(MmcPort, sector_index, sector_count, src, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ namespace ams::nxboot {
|
|||||||
sdmmc::SetSdCardWorkBuffer(SdCardPort, g_sd_work_buffer, sizeof(g_sd_work_buffer));
|
sdmmc::SetSdCardWorkBuffer(SdCardPort, g_sd_work_buffer, sizeof(g_sd_work_buffer));
|
||||||
|
|
||||||
/* Activate the SD card. */
|
/* Activate the SD card. */
|
||||||
return sdmmc::Activate(SdCardPort);
|
R_RETURN(sdmmc::Activate(SdCardPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinalizeSdCard() {
|
void FinalizeSdCard() {
|
||||||
@@ -90,19 +90,19 @@ namespace ams::nxboot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
Result CheckSdCardConnection(sdmmc::SpeedMode *out_sm, sdmmc::BusWidth *out_bw) {
|
||||||
return sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort);
|
R_RETURN(sdmmc::CheckSdCardConnection(out_sm, out_bw, SdCardPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetSdCardMemoryCapacity(u32 *out_num_sectors) {
|
Result GetSdCardMemoryCapacity(u32 *out_num_sectors) {
|
||||||
return sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort);
|
R_RETURN(sdmmc::GetDeviceMemoryCapacity(out_num_sectors, SdCardPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
Result ReadSdCard(void *dst, size_t size, size_t sector_index, size_t sector_count) {
|
||||||
return sdmmc::Read(dst, size, SdCardPort, sector_index, sector_count);
|
R_RETURN(sdmmc::Read(dst, size, SdCardPort, sector_index, sector_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
Result WriteSdCard(size_t sector_index, size_t sector_count, const void *src, size_t size) {
|
||||||
return sdmmc::Write(SdCardPort, sector_index, sector_count, src, size);
|
R_RETURN(sdmmc::Write(SdCardPort, sector_index, sector_count, src, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = 0d161b8588aa6482b84f3c44dd001055b01a047f
|
commit = b91294d3b9960eafef6d5d80b08870d427324bc9
|
||||||
parent = 4efa5d7dd0bfbdf89a6261af0aef3878ca784b05
|
parent = 3545c0aac2cdfc1f6f897e8c669a8e33358b3ece
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.1
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ endif
|
|||||||
|
|
||||||
ifeq ($(ATMOSPHERE_BOARD),nx-hac-001)
|
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)
|
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
|
else
|
||||||
export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $@.map)
|
export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $@.map)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace ams::ddsf {
|
|||||||
|
|
||||||
/* Attach the session. */
|
/* Attach the session. */
|
||||||
m_session_list.push_back(*session);
|
m_session_list.push_back(*session);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetachSession(ISession *session) {
|
void DetachSession(ISession *session) {
|
||||||
@@ -113,12 +113,12 @@ namespace ams::ddsf {
|
|||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Result ForEachSession(F f, bool return_on_fail) {
|
Result ForEachSession(F f, bool return_on_fail) {
|
||||||
return impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail);
|
R_RETURN(impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Result ForEachSession(F f, bool return_on_fail) const {
|
Result ForEachSession(F f, bool return_on_fail) const {
|
||||||
return impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail);
|
R_RETURN(impl::ForEach(m_session_list_lock, m_session_list, f, return_on_fail));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
|||||||
@@ -76,12 +76,12 @@ namespace ams::ddsf {
|
|||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Result ForEachDevice(F f, bool return_on_fail) {
|
Result ForEachDevice(F f, bool return_on_fail) {
|
||||||
return impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail);
|
R_RETURN(impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
Result ForEachDevice(F f, bool return_on_fail) const {
|
Result ForEachDevice(F f, bool return_on_fail) const {
|
||||||
return impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail);
|
R_RETURN(impl::ForEach(m_device_list_lock, m_device_list, f, return_on_fail));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ namespace ams::ddsf::impl {
|
|||||||
for (auto && it : list) {
|
for (auto && it : list) {
|
||||||
if (const auto cur_result = f(std::addressof(it)); R_FAILED(cur_result)) {
|
if (const auto cur_result = f(std::addressof(it)); R_FAILED(cur_result)) {
|
||||||
if (return_on_fail) {
|
if (return_on_fail) {
|
||||||
return cur_result;
|
R_RETURN(cur_result);
|
||||||
} else if (R_SUCCEEDED(result)) {
|
} else if (R_SUCCEEDED(result)) {
|
||||||
result = cur_result;
|
result = cur_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
R_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename List, typename F, typename Lock>
|
template<typename List, typename F, typename Lock>
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include <stratosphere/fs/fsa/fs_registrar.hpp>
|
#include <stratosphere/fs/fsa/fs_registrar.hpp>
|
||||||
#include <stratosphere/fs/fs_remote_filesystem.hpp>
|
#include <stratosphere/fs/fs_remote_filesystem.hpp>
|
||||||
#include <stratosphere/fs/fs_read_only_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_istorage.hpp>
|
||||||
#include <stratosphere/fs/fs_i_event_notifier.hpp>
|
#include <stratosphere/fs/fs_i_event_notifier.hpp>
|
||||||
#include <stratosphere/fs/fs_substorage.hpp>
|
#include <stratosphere/fs/fs_substorage.hpp>
|
||||||
@@ -66,4 +65,5 @@
|
|||||||
#include <stratosphere/fs/fs_program_index_map_info.hpp>
|
#include <stratosphere/fs/fs_program_index_map_info.hpp>
|
||||||
#include <stratosphere/fs/impl/fs_access_log_impl.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_hash_generator_factory_selector.hpp>
|
||||||
|
#include <stratosphere/fs/impl/fs_storage_service_object_adapter.hpp>
|
||||||
#include <stratosphere/fs/fs_api.hpp>
|
#include <stratosphere/fs/fs_api.hpp>
|
||||||
|
|||||||
@@ -20,9 +20,11 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
class HierarchicalRomFileTable {
|
class HierarchicalRomFileTable {
|
||||||
public:
|
public:
|
||||||
using Position = u32;
|
using Position = u32;
|
||||||
|
using StorageSizeType = u32;
|
||||||
|
|
||||||
struct FindPosition {
|
struct FindPosition {
|
||||||
Position next_dir;
|
Position next_dir;
|
||||||
@@ -30,8 +32,7 @@ namespace ams::fs {
|
|||||||
};
|
};
|
||||||
static_assert(util::is_pod<FindPosition>::value);
|
static_assert(util::is_pod<FindPosition>::value);
|
||||||
|
|
||||||
using DirectoryInfo = RomDirectoryInfo;
|
using FileInfo = RomFileInfo;
|
||||||
using FileInfo = RomFileInfo;
|
|
||||||
|
|
||||||
static constexpr RomFileId PositionToFileId(Position pos) {
|
static constexpr RomFileId PositionToFileId(Position pos) {
|
||||||
return static_cast<RomFileId>(pos);
|
return static_cast<RomFileId>(pos);
|
||||||
@@ -80,23 +81,23 @@ namespace ams::fs {
|
|||||||
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
using Base = KeyValueRomStorageTemplate<ImplKeyType, ValueType, MaxKeyLength>;
|
||||||
public:
|
public:
|
||||||
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
Result Add(Position *out, const ClientKeyType &key, const Value &value) {
|
||||||
return Base::AddInternal(out, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar), value);
|
R_RETURN(Base::AddInternal(out, key.key, key.Hash(), key.name.begin(), key.name.length(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) {
|
Result Get(Position *out_pos, Value *out_val, const ClientKeyType &key) {
|
||||||
return Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.path, key.name.length * sizeof(RomPathChar));
|
R_RETURN(Base::GetInternal(out_pos, out_val, key.key, key.Hash(), key.name.begin(), key.name.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
|
Result GetByPosition(ImplKey *out_key, Value *out_val, Position pos) {
|
||||||
return Base::GetByPosition(out_key, out_val, pos);
|
R_RETURN(Base::GetByPosition(out_key, out_val, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetByPosition(ImplKey *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
Result GetByPosition(ImplKey *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||||
return Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos);
|
R_RETURN(Base::GetByPosition(out_key, out_val, out_aux, out_aux_size, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetByPosition(Position pos, const Value &value) {
|
Result SetByPosition(Position pos, const Value &value) {
|
||||||
return Base::SetByPosition(pos, value);
|
R_RETURN(Base::SetByPosition(pos, value));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,16 +122,15 @@ namespace ams::fs {
|
|||||||
|
|
||||||
constexpr u32 Hash() const {
|
constexpr u32 Hash() const {
|
||||||
u32 hash = this->key.parent ^ 123456789;
|
u32 hash = this->key.parent ^ 123456789;
|
||||||
const RomPathChar * name = this->name.path;
|
const RomPathChar * cur = this->name.begin();
|
||||||
const RomPathChar * const end = name + this->name.length;
|
const RomPathChar * const end = this->name.end();
|
||||||
while (name < end) {
|
while (cur < end) {
|
||||||
const u32 cur = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(name++)));
|
const u32 c = static_cast<u32>(static_cast<std::make_unsigned<RomPathChar>::type>(*(cur++)));
|
||||||
hash = ((hash >> 5) | (hash << 27)) ^ cur;
|
hash = ((hash >> 5) | (hash << 27)) ^ c;
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<EntryKey>::value);
|
|
||||||
|
|
||||||
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
|
using DirectoryEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomDirectoryEntry>;
|
||||||
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
|
using FileEntryMapTable = EntryMapTable<RomEntryKey, EntryKey, RomFileEntry>;
|
||||||
@@ -138,35 +138,24 @@ namespace ams::fs {
|
|||||||
DirectoryEntryMapTable m_dir_table;
|
DirectoryEntryMapTable m_dir_table;
|
||||||
FileEntryMapTable m_file_table;
|
FileEntryMapTable m_file_table;
|
||||||
public:
|
public:
|
||||||
static s64 QueryDirectoryEntryBucketStorageSize(s64 count);
|
static s64 QueryDirectoryEntryBucketStorageSize(StorageSizeType count);
|
||||||
static size_t QueryDirectoryEntrySize(size_t aux_size);
|
static s64 QueryDirectoryEntrySize(StorageSizeType aux_size);
|
||||||
static s64 QueryFileEntryBucketStorageSize(s64 count);
|
static s64 QueryFileEntryBucketStorageSize(StorageSizeType count);
|
||||||
static size_t QueryFileEntrySize(size_t aux_size);
|
static s64 QueryFileEntrySize(StorageSizeType aux_size);
|
||||||
|
|
||||||
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
|
static Result Format(SubStorage dir_bucket, SubStorage file_bucket);
|
||||||
public:
|
public:
|
||||||
HierarchicalRomFileTable();
|
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);
|
Result Initialize(SubStorage dir_bucket, SubStorage dir_entry, SubStorage file_bucket, SubStorage file_entry);
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
Result CreateRootDirectory();
|
Result CreateRootDirectory();
|
||||||
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path, const DirectoryInfo &info);
|
Result CreateDirectory(RomDirectoryId *out, const RomPathChar *path);
|
||||||
Result CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info);
|
Result CreateFile(RomFileId *out, const RomPathChar *path, const FileInfo &info);
|
||||||
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path);
|
Result ConvertPathToDirectoryId(RomDirectoryId *out, const RomPathChar *path);
|
||||||
Result ConvertPathToFileId(RomFileId *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, const RomPathChar *path);
|
||||||
Result OpenFile(FileInfo *out, RomFileId id);
|
Result OpenFile(FileInfo *out, RomFileId id);
|
||||||
|
|
||||||
@@ -178,7 +167,7 @@ namespace ams::fs {
|
|||||||
|
|
||||||
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
|
Result QueryRomFileSystemSize(s64 *out_dir_entry_size, s64 *out_file_entry_size);
|
||||||
private:
|
private:
|
||||||
Result GetGrandParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path);
|
Result GetParent(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, Position pos, RomPathTool::RomEntryName name, const RomPathChar *path);
|
||||||
|
|
||||||
Result FindParentDirectoryRecursive(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, RomPathTool::PathParser *parser, const RomPathChar *path);
|
Result FindParentDirectoryRecursive(Position *out_pos, EntryKey *out_dir_key, RomDirectoryEntry *out_dir_entry, RomPathTool::PathParser *parser, const RomPathChar *path);
|
||||||
|
|
||||||
@@ -194,8 +183,6 @@ namespace ams::fs {
|
|||||||
Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key);
|
Result GetFileEntry(Position *out_pos, RomFileEntry *out_entry, const EntryKey &key);
|
||||||
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
|
Result GetFileEntry(RomFileEntry *out_entry, RomFileId id);
|
||||||
|
|
||||||
Result GetDirectoryInformation(DirectoryInfo *out, const EntryKey &key);
|
|
||||||
|
|
||||||
Result OpenFile(FileInfo *out, const EntryKey &key);
|
Result OpenFile(FileInfo *out, const EntryKey &key);
|
||||||
|
|
||||||
Result FindOpen(FindPosition *out, const EntryKey &key);
|
Result FindOpen(FindPosition *out, const EntryKey &key);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
template<typename KeyType, typename ValueType, size_t MaxAuxiliarySize>
|
||||||
class KeyValueRomStorageTemplate {
|
class KeyValueRomStorageTemplate {
|
||||||
public:
|
public:
|
||||||
@@ -27,6 +28,8 @@ namespace ams::fs {
|
|||||||
using Position = u32;
|
using Position = u32;
|
||||||
using BucketIndex = s64;
|
using BucketIndex = s64;
|
||||||
|
|
||||||
|
using StorageSizeType = u32;
|
||||||
|
|
||||||
struct FindIndex {
|
struct FindIndex {
|
||||||
BucketIndex ind;
|
BucketIndex ind;
|
||||||
Position pos;
|
Position pos;
|
||||||
@@ -39,7 +42,7 @@ namespace ams::fs {
|
|||||||
Key key;
|
Key key;
|
||||||
Value value;
|
Value value;
|
||||||
Position next;
|
Position next;
|
||||||
u32 size;
|
StorageSizeType size;
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<Element>::value);
|
static_assert(util::is_pod<Element>::value);
|
||||||
private:
|
private:
|
||||||
@@ -53,53 +56,41 @@ namespace ams::fs {
|
|||||||
return num * sizeof(Position);
|
return num * sizeof(Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr s64 QueryBucketCount(s64 size) {
|
static constexpr s64 QueryBucketCount(StorageSizeType size) {
|
||||||
return size / sizeof(Position);
|
return size / sizeof(Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr size_t QueryEntrySize(size_t aux_size) {
|
static constexpr size_t QueryEntrySize(StorageSizeType aux_size) {
|
||||||
return util::AlignUp(sizeof(Element) + aux_size, alignof(Element));
|
return util::AlignUp<size_t>(sizeof(Element) + aux_size, alignof(Element));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result Format(SubStorage bucket, s64 count) {
|
static Result Format(SubStorage bucket, StorageSizeType count) {
|
||||||
const Position pos = InvalidPosition;
|
const Position pos = InvalidPosition;
|
||||||
for (s64 i = 0; i < count; i++) {
|
for (auto i = 0u; i < count; i++) {
|
||||||
R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
|
R_TRY(bucket.Write(i * sizeof(pos), std::addressof(pos), sizeof(pos)));
|
||||||
}
|
}
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ }
|
constexpr KeyValueRomStorageTemplate() : m_bucket_count(), m_bucket_storage(), m_kv_storage(), m_total_entry_size(), m_entry_count() { /* ... */ }
|
||||||
|
|
||||||
Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) {
|
Result Initialize(const SubStorage &bucket, s64 count, const SubStorage &kv) {
|
||||||
AMS_ASSERT(count > 0);
|
AMS_ASSERT(count > 0);
|
||||||
m_bucket_storage = bucket;
|
m_bucket_storage = bucket;
|
||||||
m_bucket_count = count;
|
m_bucket_count = count;
|
||||||
m_kv_storage = kv;
|
m_kv_storage = kv;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Finalize() {
|
void Finalize() {
|
||||||
m_bucket_storage = SubStorage();
|
m_bucket_storage = SubStorage();
|
||||||
m_kv_storage = SubStorage();
|
|
||||||
m_bucket_count = 0;
|
m_bucket_count = 0;
|
||||||
|
m_kv_storage = SubStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 GetTotalEntrySize() const {
|
s64 GetTotalEntrySize() const {
|
||||||
return m_total_entry_size;
|
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:
|
protected:
|
||||||
Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
Result AddInternal(Position *out, const Key &key, u32 hash_key, const void *aux, size_t aux_size, const Value &value) {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
@@ -116,18 +107,18 @@ namespace ams::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Position pos;
|
Position pos;
|
||||||
R_TRY(this->AllocateEntry(std::addressof(pos), aux_size));
|
R_TRY(this->AllocateEntry(std::addressof(pos), static_cast<StorageSizeType>(aux_size)));
|
||||||
|
|
||||||
Position next_pos;
|
Position next_pos;
|
||||||
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
|
R_TRY(this->LinkEntry(std::addressof(next_pos), pos, hash_key));
|
||||||
|
|
||||||
const Element elem = { key, value, next_pos, static_cast<u32>(aux_size) };
|
const Element elem = { key, value, next_pos, static_cast<StorageSizeType>(aux_size) };
|
||||||
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
|
R_TRY(this->WriteKeyValue(std::addressof(elem), pos, aux, aux_size));
|
||||||
|
|
||||||
*out = pos;
|
*out = pos;
|
||||||
m_entry_count++;
|
m_entry_count++;
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetInternal(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
Result GetInternal(Position *out_pos, Value *out_val, const Key &key, u32 hash_key, const void *aux, size_t aux_size) {
|
||||||
@@ -141,7 +132,7 @@ namespace ams::fs {
|
|||||||
|
|
||||||
*out_pos = pos;
|
*out_pos = pos;
|
||||||
*out_val = elem.value;
|
*out_val = elem.value;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetByPosition(Key *out_key, Value *out_val, Position pos) {
|
Result GetByPosition(Key *out_key, Value *out_val, Position pos) {
|
||||||
@@ -153,7 +144,7 @@ namespace ams::fs {
|
|||||||
|
|
||||||
*out_key = elem.key;
|
*out_key = elem.key;
|
||||||
*out_val = elem.value;
|
*out_val = elem.value;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
Result GetByPosition(Key *out_key, Value *out_val, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||||
@@ -167,14 +158,14 @@ namespace ams::fs {
|
|||||||
|
|
||||||
*out_key = elem.key;
|
*out_key = elem.key;
|
||||||
*out_val = elem.value;
|
*out_val = elem.value;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetByPosition(Position pos, const Value &value) {
|
Result SetByPosition(Position pos, const Value &value) {
|
||||||
Element elem;
|
Element elem;
|
||||||
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
|
R_TRY(this->ReadKeyValue(std::addressof(elem), pos));
|
||||||
elem.value = value;
|
elem.value = value;
|
||||||
return this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0);
|
R_RETURN(this->WriteKeyValue(std::addressof(elem), pos, nullptr, 0));
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
BucketIndex HashToBucket(u32 hash_key) const {
|
BucketIndex HashToBucket(u32 hash_key) const {
|
||||||
@@ -202,17 +193,16 @@ namespace ams::fs {
|
|||||||
|
|
||||||
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
R_UNLESS(cur != InvalidPosition, fs::ResultDbmKeyNotFound());
|
||||||
|
|
||||||
u8 *buf = static_cast<u8 *>(::ams::fs::impl::Allocate(MaxAuxiliarySize));
|
auto buf = ::ams::fs::impl::MakeUnique<u8[]>(MaxAuxiliarySize);
|
||||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedInDbmRomKeyValueStorage());
|
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||||
ON_SCOPE_EXIT { ::ams::fs::impl::Deallocate(buf, MaxAuxiliarySize); };
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
size_t cur_aux_size;
|
size_t cur_aux_size;
|
||||||
R_TRY(this->ReadKeyValue(out_elem, buf, std::addressof(cur_aux_size), cur));
|
R_TRY(this->ReadKeyValue(out_elem, buf.get(), std::addressof(cur_aux_size), cur));
|
||||||
|
|
||||||
if (key.IsEqual(out_elem->key, aux, aux_size, buf, cur_aux_size)) {
|
if (key.IsEqual(out_elem->key, aux, aux_size, buf.get(), cur_aux_size)) {
|
||||||
*out_pos = cur;
|
*out_pos = cur;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_prev = cur;
|
*out_prev = cur;
|
||||||
@@ -221,18 +211,18 @@ namespace ams::fs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AllocateEntry(Position *out, size_t aux_size) {
|
Result AllocateEntry(Position *out, StorageSizeType aux_size) {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
|
|
||||||
s64 kv_size;
|
s64 kv_size;
|
||||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||||
const size_t end_pos = m_total_entry_size + sizeof(Element) + aux_size;
|
const size_t end_pos = m_total_entry_size + sizeof(Element) + static_cast<size_t>(aux_size);
|
||||||
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
|
R_UNLESS(end_pos <= static_cast<size_t>(kv_size), fs::ResultDbmKeyFull());
|
||||||
|
|
||||||
*out = static_cast<Position>(m_total_entry_size);
|
*out = static_cast<Position>(m_total_entry_size);
|
||||||
|
|
||||||
m_total_entry_size = util::AlignUp(static_cast<s64>(end_pos), alignof(Position));
|
m_total_entry_size = util::AlignUp<s64>(static_cast<s64>(end_pos), alignof(Position));
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
|
Result LinkEntry(Position *out, Position pos, u32 hash_key) {
|
||||||
@@ -250,7 +240,7 @@ namespace ams::fs {
|
|||||||
R_TRY(this->WriteBucket(pos, ind));
|
R_TRY(this->WriteBucket(pos, ind));
|
||||||
|
|
||||||
*out = next;
|
*out = next;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadBucket(Position *out, BucketIndex ind) {
|
Result ReadBucket(Position *out, BucketIndex ind) {
|
||||||
@@ -258,14 +248,14 @@ namespace ams::fs {
|
|||||||
AMS_ASSERT(ind < m_bucket_count);
|
AMS_ASSERT(ind < m_bucket_count);
|
||||||
|
|
||||||
const s64 offset = ind * sizeof(Position);
|
const s64 offset = ind * sizeof(Position);
|
||||||
return m_bucket_storage.Read(offset, out, sizeof(*out));
|
R_RETURN(m_bucket_storage.Read(offset, out, sizeof(*out)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteBucket(Position pos, BucketIndex ind) {
|
Result WriteBucket(Position pos, BucketIndex ind) {
|
||||||
AMS_ASSERT(ind < m_bucket_count);
|
AMS_ASSERT(ind < m_bucket_count);
|
||||||
|
|
||||||
const s64 offset = ind * sizeof(Position);
|
const s64 offset = ind * sizeof(Position);
|
||||||
return m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos));
|
R_RETURN(m_bucket_storage.Write(offset, std::addressof(pos), sizeof(pos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadKeyValue(Element *out, Position pos) {
|
Result ReadKeyValue(Element *out, Position pos) {
|
||||||
@@ -275,7 +265,7 @@ namespace ams::fs {
|
|||||||
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
R_TRY(m_kv_storage.GetSize(std::addressof(kv_size)));
|
||||||
AMS_ASSERT(pos < kv_size);
|
AMS_ASSERT(pos < kv_size);
|
||||||
|
|
||||||
return m_kv_storage.Read(pos, out, sizeof(*out));
|
R_RETURN(m_kv_storage.Read(pos, out, sizeof(*out)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) {
|
Result ReadKeyValue(Element *out, void *out_aux, size_t *out_aux_size, Position pos) {
|
||||||
@@ -290,7 +280,7 @@ namespace ams::fs {
|
|||||||
R_TRY(m_kv_storage.Read(pos + sizeof(*out), out_aux, out->size));
|
R_TRY(m_kv_storage.Read(pos + sizeof(*out), out_aux, out->size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size) {
|
Result WriteKeyValue(const Element *elem, Position pos, const void *aux, size_t aux_size) {
|
||||||
@@ -307,7 +297,7 @@ namespace ams::fs {
|
|||||||
R_TRY(m_kv_storage.Write(pos + sizeof(*elem), aux, aux_size));
|
R_TRY(m_kv_storage.Write(pos + sizeof(*elem), aux, aux_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,34 +18,60 @@
|
|||||||
|
|
||||||
namespace ams::fs::RomPathTool {
|
namespace ams::fs::RomPathTool {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
|
|
||||||
constexpr inline u32 MaxPathLength = 0x300;
|
constexpr inline u32 MaxPathLength = 0x300;
|
||||||
|
|
||||||
struct RomEntryName {
|
constexpr ALWAYS_INLINE bool IsSeparator(RomPathChar c) {
|
||||||
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;
|
return c == RomStringTraits::DirectorySeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool IsNullTerminator(RomPathChar c) {
|
constexpr ALWAYS_INLINE bool IsNullTerminator(RomPathChar c) {
|
||||||
return c == RomStringTraits::NullTerminator;
|
return c == RomStringTraits::NullTerminator;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool IsDot(RomPathChar c) {
|
constexpr ALWAYS_INLINE bool IsDot(RomPathChar c) {
|
||||||
return c == RomStringTraits::Dot;
|
return c == RomStringTraits::Dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool IsCurrentDirectory(const RomEntryName &name) {
|
class RomEntryName {
|
||||||
return name.length == 1 && IsDot(name.path[0]);
|
private:
|
||||||
}
|
const RomPathChar *m_path;
|
||||||
|
size_t m_length;
|
||||||
|
public:
|
||||||
|
constexpr RomEntryName() : m_path(nullptr), m_length(0) {
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void Initialize(const RomPathChar *p, size_t len) {
|
||||||
|
m_path = p;
|
||||||
|
m_length = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsCurrentDirectory() const {
|
||||||
|
return m_length == 1 && IsDot(m_path[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsParentDirectory() const {
|
||||||
|
return m_length == 2 && IsDot(m_path[0]) && IsDot(m_path[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsRootDirectory() const {
|
||||||
|
return m_length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const RomPathChar *begin() const {
|
||||||
|
return m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const RomPathChar *end() const {
|
||||||
|
return m_path + m_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t length() const {
|
||||||
|
return m_length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
constexpr inline bool IsCurrentDirectory(const RomPathChar *p, size_t length) {
|
||||||
AMS_ASSERT(p != nullptr);
|
AMS_ASSERT(p != nullptr);
|
||||||
@@ -57,10 +83,6 @@ namespace ams::fs::RomPathTool {
|
|||||||
return IsDot(p[0]) && IsNullTerminator(p[1]);
|
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) {
|
constexpr inline bool IsParentDirectory(const RomPathChar *p) {
|
||||||
AMS_ASSERT(p != nullptr);
|
AMS_ASSERT(p != nullptr);
|
||||||
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
return IsDot(p[0]) && IsDot(p[1]) && IsNullTerminator(p[2]);
|
||||||
|
|||||||
@@ -18,9 +18,10 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
using RomPathChar = char;
|
using RomPathChar = char;
|
||||||
using RomFileId = s32;
|
using RomFileId = u32;
|
||||||
using RomDirectoryId = s32;
|
using RomDirectoryId = u32;
|
||||||
|
|
||||||
struct RomFileSystemInformation {
|
struct RomFileSystemInformation {
|
||||||
s64 size;
|
s64 size;
|
||||||
@@ -37,11 +38,6 @@ namespace ams::fs {
|
|||||||
static_assert(util::is_pod<RomFileSystemInformation>::value);
|
static_assert(util::is_pod<RomFileSystemInformation>::value);
|
||||||
static_assert(sizeof(RomFileSystemInformation) == 0x50);
|
static_assert(sizeof(RomFileSystemInformation) == 0x50);
|
||||||
|
|
||||||
struct RomDirectoryInfo {
|
|
||||||
/* ... */
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<RomDirectoryInfo>::value);
|
|
||||||
|
|
||||||
struct RomFileInfo {
|
struct RomFileInfo {
|
||||||
Int64 offset;
|
Int64 offset;
|
||||||
Int64 size;
|
Int64 size;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class DirectoryPathParser {
|
class DirectoryPathParser {
|
||||||
NON_COPYABLE(DirectoryPathParser);
|
NON_COPYABLE(DirectoryPathParser);
|
||||||
NON_MOVEABLE(DirectoryPathParser);
|
NON_MOVEABLE(DirectoryPathParser);
|
||||||
@@ -101,10 +102,9 @@ namespace ams::fs {
|
|||||||
s32 i;
|
s32 i;
|
||||||
for (i = m_position; m_buffer[i] != StringTraits::DirectorySeparator; ++i) {
|
for (i = m_position; m_buffer[i] != StringTraits::DirectorySeparator; ++i) {
|
||||||
if (m_buffer[i] == StringTraits::NullTerminator) {
|
if (m_buffer[i] == StringTraits::NullTerminator) {
|
||||||
if (i == m_position) {
|
char * const ret = (i != m_position) ? m_buffer + m_position : nullptr;
|
||||||
m_position = -1;
|
m_position = -1;
|
||||||
return nullptr;
|
return ret;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class FileStorage : public IStorage, public impl::Newable {
|
class FileStorage : public IStorage, public impl::Newable {
|
||||||
NON_COPYABLE(FileStorage);
|
NON_COPYABLE(FileStorage);
|
||||||
NON_MOVEABLE(FileStorage);
|
NON_MOVEABLE(FileStorage);
|
||||||
@@ -74,6 +75,7 @@ namespace ams::fs {
|
|||||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
|
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 {
|
class FileStorageBasedFileSystem : public FileStorage {
|
||||||
NON_COPYABLE(FileStorageBasedFileSystem);
|
NON_COPYABLE(FileStorageBasedFileSystem);
|
||||||
NON_MOVEABLE(FileStorageBasedFileSystem);
|
NON_MOVEABLE(FileStorageBasedFileSystem);
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
|
|
||||||
enum AccessLogMode : u32 {
|
enum AccessLogMode : u32 {
|
||||||
AccessLogMode_None = 0,
|
AccessLogMode_None = 0,
|
||||||
AccessLogMode_Log = 1,
|
AccessLogMode_Log = 1,
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
|
|
||||||
void InitializeForSystem();
|
void InitializeForSystem();
|
||||||
void InitializeWithMultiSessionForSystem();
|
void InitializeWithMultiSessionForSystem();
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
|
|
||||||
Result MountApplicationPackage(const char *name, const char *common_path);
|
Result MountApplicationPackage(const char *name, const char *common_path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
|
|
||||||
enum class BisPartitionId {
|
enum class BisPartitionId {
|
||||||
/* Boot0 */
|
/* Boot0 */
|
||||||
BootPartition1Root = 0,
|
BootPartition1Root = 0,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
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 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);
|
Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, ncm::ProgramId program_id, bool is_hbl, bool is_specific);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
struct CodeVerificationData : public ams::sf::LargeData {
|
struct CodeVerificationData : public ams::sf::LargeData {
|
||||||
u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize];
|
u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize];
|
||||||
u8 target_hash[crypto::Rsa2048PssSha256Verifier::HashSize];
|
u8 target_hash[crypto::Rsa2048PssSha256Verifier::HashSize];
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
struct Int64 {
|
struct Int64 {
|
||||||
u32 low;
|
u32 low;
|
||||||
u32 high;
|
u32 high;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
ContentType_Meta = 0,
|
ContentType_Meta = 0,
|
||||||
ContentType_Control = 1,
|
ContentType_Control = 1,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum class ContentStorageId : u32 {
|
enum class ContentStorageId : u32 {
|
||||||
System = 0,
|
System = 0,
|
||||||
User = 1,
|
User = 1,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
Result MountDeviceSaveData(const char *name);
|
Result MountDeviceSaveData(const char *name);
|
||||||
Result MountDeviceSaveData(const char *name, const ncm::ApplicationId application_id);
|
Result MountDeviceSaveData(const char *name, const ncm::ApplicationId application_id);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
constexpr inline size_t EntryNameLengthMax = 0x300;
|
constexpr inline size_t EntryNameLengthMax = 0x300;
|
||||||
|
|
||||||
struct DirectoryEntry {
|
struct DirectoryEntry {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace ams::fs {
|
|||||||
|
|
||||||
namespace fsa {
|
namespace fsa {
|
||||||
|
|
||||||
class IFile;
|
class IFileSystem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
struct FileTimeStamp {
|
struct FileTimeStamp {
|
||||||
time::PosixTime create;
|
time::PosixTime create;
|
||||||
time::PosixTime modify;
|
time::PosixTime modify;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum class GameCardPartition {
|
enum class GameCardPartition {
|
||||||
Update = 0,
|
Update = 0,
|
||||||
Normal = 1,
|
Normal = 1,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum MountHostOptionFlag : u32 {
|
enum MountHostOptionFlag : u32 {
|
||||||
MountHostOptionFlag_None = (0 << 0),
|
MountHostOptionFlag_None = (0 << 0),
|
||||||
MountHostOptionFlag_PseudoCaseSensitive = (1 << 0),
|
MountHostOptionFlag_PseudoCaseSensitive = (1 << 0),
|
||||||
|
|||||||
@@ -18,13 +18,14 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IEventNotifier {
|
class IEventNotifier {
|
||||||
public:
|
public:
|
||||||
virtual ~IEventNotifier() { /* ... */ }
|
virtual ~IEventNotifier() { /* ... */ }
|
||||||
|
|
||||||
Result BindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) {
|
Result BindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) {
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
return this->DoBindEvent(out, clear_mode);
|
R_RETURN(this->DoBindEvent(out, clear_mode));
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) = 0;
|
virtual Result DoBindEvent(os::SystemEventType *out, os::EventClearMode clear_mode) = 0;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum class ImageDirectoryId {
|
enum class ImageDirectoryId {
|
||||||
Nand = 0,
|
Nand = 0,
|
||||||
SdCard = 1,
|
SdCard = 1,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 14.3.0.0 */
|
||||||
class IStorage {
|
class IStorage {
|
||||||
public:
|
public:
|
||||||
virtual ~IStorage() { /* ... */ }
|
virtual ~IStorage() { /* ... */ }
|
||||||
@@ -37,28 +38,41 @@ namespace ams::fs {
|
|||||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) = 0;
|
virtual Result OperateRange(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) {
|
virtual Result OperateRange(OperationId op_id, s64 offset, s64 size) {
|
||||||
return this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0);
|
R_RETURN(this->OperateRange(nullptr, 0, op_id, offset, size, nullptr, 0));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static inline bool CheckAccessRange(s64 offset, s64 size, s64 total_size) {
|
static inline Result CheckAccessRange(s64 offset, s64 size, s64 total_size) {
|
||||||
return offset >= 0 &&
|
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||||
size >= 0 &&
|
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||||
size <= total_size &&
|
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||||
offset <= (total_size - size);
|
R_UNLESS(offset + size <= total_size, fs::ResultOutOfRange());
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
static ALWAYS_INLINE Result CheckAccessRange(s64 offset, size_t size, s64 total_size) {
|
||||||
return CheckAccessRange(offset, static_cast<s64>(size), total_size);
|
R_RETURN(CheckAccessRange(offset, static_cast<s64>(size), total_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CheckOffsetAndSize(s64 offset, s64 size) {
|
static inline Result CheckOffsetAndSize(s64 offset, s64 size) {
|
||||||
return offset >= 0 &&
|
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||||
size >= 0 &&
|
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||||
offset <= (offset + size);
|
R_UNLESS(util::CanAddWithoutOverflow<s64>(offset, size), fs::ResultOutOfRange());
|
||||||
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool CheckOffsetAndSize(s64 offset, size_t size) {
|
static ALWAYS_INLINE Result CheckOffsetAndSize(s64 offset, size_t size) {
|
||||||
return CheckOffsetAndSize(offset, static_cast<s64>(size));
|
R_RETURN(CheckOffsetAndSize(offset, static_cast<s64>(size)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Result CheckOffsetAndSizeWithResult(s64 offset, s64 size, Result fail_result) {
|
||||||
|
R_TRY_CATCH(CheckOffsetAndSize(offset, size)) {
|
||||||
|
R_CONVERT_ALL(fail_result);
|
||||||
|
} R_END_TRY_CATCH;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE Result CheckOffsetAndSizeWithResult(s64 offset, size_t size, Result fail_result) {
|
||||||
|
R_RETURN(CheckOffsetAndSizeWithResult(offset, static_cast<s64>(size), fail_result));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,32 +95,35 @@ namespace ams::fs {
|
|||||||
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
|
virtual ~ReadOnlyStorageAdapter() { /* ... */ }
|
||||||
public:
|
public:
|
||||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||||
return m_storage->Read(offset, buffer, size);
|
R_RETURN(m_storage->Read(offset, buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return m_storage->Flush();
|
R_RETURN(m_storage->Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
return m_storage->GetSize(out);
|
R_RETURN(m_storage->GetSize(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||||
return m_storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
|
R_RETURN(m_storage->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
/* TODO: Better result? Is it possible to get a more specific one? */
|
/* TODO: Better result? Is it possible to get a more specific one? */
|
||||||
AMS_UNUSED(offset, buffer, size);
|
AMS_UNUSED(offset, buffer, size);
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
/* TODO: Better result? Is it possible to get a more specific one? */
|
/* TODO: Better result? Is it possible to get a more specific one? */
|
||||||
AMS_UNUSED(size);
|
AMS_UNUSED(size);
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept PointerToStorage = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::IStorage>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
using AllocateFunction = void *(*)(size_t);
|
using AllocateFunction = void *(*)(size_t);
|
||||||
using DeallocateFunction = void (*)(void *, size_t);
|
using DeallocateFunction = void (*)(void *, size_t);
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ namespace ams::fs {
|
|||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
|
class Newable;
|
||||||
|
|
||||||
void *Allocate(size_t size);
|
void *Allocate(size_t size);
|
||||||
void Deallocate(void *ptr, size_t size);
|
void Deallocate(void *ptr, size_t size);
|
||||||
|
|
||||||
@@ -129,20 +132,27 @@ namespace ams::fs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::unique_ptr<T, Deleter> MakeUnique() {
|
auto MakeUnique() {
|
||||||
static_assert(util::is_pod<T>::value);
|
/* Check that we're not using MakeUnique unnecessarily. */
|
||||||
|
static_assert(!std::derived_from<T, ::ams::fs::impl::Newable>);
|
||||||
|
|
||||||
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
|
return std::unique_ptr<T, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(sizeof(T))), Deleter(sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ArrayT>
|
template<typename ArrayT>
|
||||||
std::unique_ptr<ArrayT, Deleter> MakeUnique(size_t size) {
|
auto MakeUnique(size_t size) {
|
||||||
using T = typename std::remove_extent<ArrayT>::type;
|
using T = typename std::remove_extent<ArrayT>::type;
|
||||||
|
|
||||||
static_assert(util::is_pod<ArrayT>::value);
|
static_assert(util::is_pod<ArrayT>::value);
|
||||||
static_assert(std::is_array<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;
|
const size_t alloc_size = sizeof(T) * size;
|
||||||
return std::unique_ptr<ArrayT, Deleter>(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
return ReturnType(static_cast<T *>(::ams::fs::impl::Allocate(alloc_size)), Deleter(alloc_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class MemoryStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
class MemoryStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||||
private:
|
private:
|
||||||
u8 * const m_buf;
|
u8 * const m_buf;
|
||||||
@@ -33,11 +34,11 @@ namespace ams::fs {
|
|||||||
|
|
||||||
/* Validate arguments. */
|
/* Validate arguments. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
|
|
||||||
/* Copy from memory. */
|
/* Copy from memory. */
|
||||||
std::memcpy(buffer, m_buf + offset, size);
|
std::memcpy(buffer, m_buf + offset, size);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
@@ -46,25 +47,25 @@ namespace ams::fs {
|
|||||||
|
|
||||||
/* Validate arguments. */
|
/* Validate arguments. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
|
|
||||||
/* Copy to memory. */
|
/* Copy to memory. */
|
||||||
std::memcpy(m_buf + offset, buffer, size);
|
std::memcpy(m_buf + offset, buffer, size);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
*out = m_size;
|
*out = m_size;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
AMS_UNUSED(size);
|
AMS_UNUSED(size);
|
||||||
return fs::ResultUnsupportedSetSizeForMemoryStorage();
|
R_THROW(fs::ResultUnsupportedSetSizeForMemoryStorage());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||||
@@ -72,14 +73,14 @@ namespace ams::fs {
|
|||||||
|
|
||||||
switch (op_id) {
|
switch (op_id) {
|
||||||
case OperationId::Invalidate:
|
case OperationId::Invalidate:
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
case OperationId::QueryRange:
|
case OperationId::QueryRange:
|
||||||
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(dst != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(dst_size == sizeof(QueryRangeInfo), fs::ResultInvalidSize());
|
R_UNLESS(dst_size == sizeof(QueryRangeInfo), fs::ResultInvalidSize());
|
||||||
reinterpret_cast<QueryRangeInfo *>(dst)->Clear();
|
reinterpret_cast<QueryRangeInfo *>(dst)->Clear();
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
default:
|
default:
|
||||||
return fs::ResultUnsupportedOperateRangeForMemoryStorage();
|
R_THROW(fs::ResultUnsupportedOperateRangeForMemoryStorage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
constexpr inline size_t MountNameLengthMax = 15;
|
constexpr inline size_t MountNameLengthMax = 15;
|
||||||
|
|
||||||
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src);
|
Result ConvertToFsCommonPath(char *dst, size_t dst_size, const char *src);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum class OperationId : s64 {
|
enum class OperationId : s64 {
|
||||||
FillZero = 0,
|
FillZero = 0,
|
||||||
DestroySignature = 1,
|
DestroySignature = 1,
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ namespace ams::fs {
|
|||||||
|
|
||||||
class DirectoryPathParser;
|
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 {
|
class Path {
|
||||||
NON_COPYABLE(Path);
|
NON_COPYABLE(Path);
|
||||||
NON_MOVEABLE(Path);
|
NON_MOVEABLE(Path);
|
||||||
@@ -31,43 +33,115 @@ namespace ams::fs {
|
|||||||
static constexpr size_t WriteBufferAlignmentLength = 8;
|
static constexpr size_t WriteBufferAlignmentLength = 8;
|
||||||
private:
|
private:
|
||||||
friend class DirectoryPathParser;
|
friend class DirectoryPathParser;
|
||||||
private:
|
public:
|
||||||
using WriteBuffer = std::unique_ptr<char[], ::ams::fs::impl::Deleter>;
|
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:
|
private:
|
||||||
const char *m_str;
|
const char *m_str;
|
||||||
util::TypedStorage<WriteBuffer> m_write_buffer;
|
WriteBuffer m_write_buffer;
|
||||||
size_t m_write_buffer_length;
|
|
||||||
bool m_is_normalized;
|
|
||||||
public:
|
public:
|
||||||
Path() : m_str(EmptyPath), m_write_buffer_length(0), m_is_normalized(false) {
|
constexpr Path() : m_str(EmptyPath), m_write_buffer() {
|
||||||
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() {
|
constexpr Path(const char *s, util::ConstantInitializeTag) : m_str(s), m_write_buffer() {
|
||||||
if (!std::is_constant_evaluated()) {
|
m_write_buffer.SetNormalized();
|
||||||
util::DestroyAt(m_write_buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteBuffer ReleaseBuffer() {
|
constexpr ~Path() { /* ... */ }
|
||||||
|
|
||||||
|
std::unique_ptr<char[], ::ams::fs::impl::Deleter> ReleaseBuffer() {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(util::GetReference(m_write_buffer) != nullptr);
|
AMS_ASSERT(m_write_buffer.Get() != nullptr);
|
||||||
|
|
||||||
/* Reset. */
|
/* Reset. */
|
||||||
m_str = EmptyPath;
|
m_str = EmptyPath;
|
||||||
m_write_buffer_length = 0;
|
|
||||||
|
|
||||||
/* Return our write buffer. */
|
/* Release our write buffer. */
|
||||||
return std::move(util::GetReference(m_write_buffer));
|
return m_write_buffer.ReleaseBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Result SetShallowBuffer(const char *buffer) {
|
constexpr Result SetShallowBuffer(const char *buffer) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(m_write_buffer_length == 0);
|
AMS_ASSERT(m_write_buffer.GetLength() == 0);
|
||||||
|
|
||||||
/* Check the buffer is valid. */
|
/* Check the buffer is valid. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
@@ -76,44 +150,49 @@ namespace ams::fs {
|
|||||||
this->SetReadOnlyBuffer(buffer);
|
this->SetReadOnlyBuffer(buffer);
|
||||||
|
|
||||||
/* Note that we're normalized. */
|
/* Note that we're normalized. */
|
||||||
m_is_normalized = true;
|
this->SetNormalized();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GetString() const {
|
constexpr const char *GetString() const {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(m_is_normalized);
|
AMS_ASSERT(this->IsNormalized());
|
||||||
|
|
||||||
return m_str;
|
return m_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetLength() const {
|
constexpr size_t GetLength() const {
|
||||||
return std::strlen(this->GetString());
|
if (std::is_constant_evaluated()) {
|
||||||
|
return util::Strlen(this->GetString());
|
||||||
|
} else {
|
||||||
|
return std::strlen(this->GetString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsEmpty() const {
|
constexpr bool IsEmpty() const {
|
||||||
return *m_str == '\x00';
|
return *m_str == '\x00';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsMatchHead(const char *p, size_t len) const {
|
constexpr bool IsMatchHead(const char *p, size_t len) const {
|
||||||
return util::Strncmp(this->GetString(), p, len) == 0;
|
return util::Strncmp(this->GetString(), p, len) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Initialize(const Path &rhs) {
|
Result Initialize(const Path &rhs) {
|
||||||
/* Check the other path is normalized. */
|
/* Check the other path is normalized. */
|
||||||
R_UNLESS(rhs.m_is_normalized, fs::ResultNotNormalized());
|
const bool normalized = rhs.IsNormalized();
|
||||||
|
R_UNLESS(normalized, fs::ResultNotNormalized());
|
||||||
|
|
||||||
/* Allocate buffer for our path. */
|
/* Allocate buffer for our path. */
|
||||||
const auto len = rhs.GetLength();
|
const auto len = rhs.GetLength();
|
||||||
R_TRY(this->Preallocate(len + 1));
|
R_TRY(this->Preallocate(len + 1));
|
||||||
|
|
||||||
/* Copy the path. */
|
/* Copy the path. */
|
||||||
const size_t copied = util::Strlcpy<char>(util::GetReference(m_write_buffer).get(), rhs.GetString(), len + 1);
|
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), rhs.GetString(), len + 1);
|
||||||
R_UNLESS(copied == len, fs::ResultUnexpectedInPathA());
|
R_UNLESS(copied == len, fs::ResultUnexpectedInPathA());
|
||||||
|
|
||||||
/* Set normalized. */
|
/* Set normalized. */
|
||||||
m_is_normalized = rhs.m_is_normalized;
|
this->SetNormalized();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +204,7 @@ namespace ams::fs {
|
|||||||
R_TRY(this->InitializeImpl(path, len));
|
R_TRY(this->InitializeImpl(path, len));
|
||||||
|
|
||||||
/* Set not normalized. */
|
/* Set not normalized. */
|
||||||
m_is_normalized = false;
|
this->SetNotNormalized();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -134,7 +213,7 @@ namespace ams::fs {
|
|||||||
/* Check the path is valid. */
|
/* Check the path is valid. */
|
||||||
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
|
||||||
|
|
||||||
return this->Initialize(path, std::strlen(path));
|
R_RETURN(this->Initialize(path, std::strlen(path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result InitializeWithFormat(const char *fmt, ...) __attribute__((format (printf, 2, 3))) {
|
Result InitializeWithFormat(const char *fmt, ...) __attribute__((format (printf, 2, 3))) {
|
||||||
@@ -153,7 +232,7 @@ namespace ams::fs {
|
|||||||
R_TRY(this->Preallocate(len + 1));
|
R_TRY(this->Preallocate(len + 1));
|
||||||
|
|
||||||
/* Format our path into our new buffer. */
|
/* Format our path into our new buffer. */
|
||||||
const auto real_len = util::VSNPrintf(util::GetReference(m_write_buffer).get(), m_write_buffer_length, fmt, vl);
|
const auto real_len = util::VSNPrintf(m_write_buffer.Get(), m_write_buffer.GetLength(), fmt, vl);
|
||||||
AMS_ASSERT(real_len == len);
|
AMS_ASSERT(real_len == len);
|
||||||
AMS_UNUSED(real_len);
|
AMS_UNUSED(real_len);
|
||||||
|
|
||||||
@@ -161,7 +240,7 @@ namespace ams::fs {
|
|||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
|
||||||
/* Set not normalized. */
|
/* Set not normalized. */
|
||||||
m_is_normalized = false;
|
this->SetNotNormalized();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -174,12 +253,12 @@ namespace ams::fs {
|
|||||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||||
|
|
||||||
/* Replace slashes as desired. */
|
/* Replace slashes as desired. */
|
||||||
if (m_write_buffer_length > 1) {
|
if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) {
|
||||||
fs::Replace(this->GetWriteBuffer(), m_write_buffer_length - 1, '\\', '/');
|
fs::Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set not normalized. */
|
/* Set not normalized. */
|
||||||
m_is_normalized = false;
|
this->SetNotNormalized();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -192,15 +271,15 @@ namespace ams::fs {
|
|||||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||||
|
|
||||||
/* Replace slashes as desired. */
|
/* Replace slashes as desired. */
|
||||||
if (m_write_buffer_length > 1) {
|
if (m_write_buffer.GetLength() > 1) {
|
||||||
if (auto *p = this->GetWriteBuffer(); p[0] == '/' && p[1] == '/') {
|
if (auto *p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') {
|
||||||
p[0] = '\\';
|
p[0] = '\\';
|
||||||
p[1] = '\\';
|
p[1] = '\\';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set not normalized. */
|
/* Set not normalized. */
|
||||||
m_is_normalized = false;
|
this->SetNotNormalized();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -213,11 +292,11 @@ namespace ams::fs {
|
|||||||
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
R_TRY(this->InitializeImpl(path, std::strlen(path)));
|
||||||
|
|
||||||
/* Set not normalized. */
|
/* Set not normalized. */
|
||||||
m_is_normalized = false;
|
this->SetNotNormalized();
|
||||||
|
|
||||||
/* Replace unc as desired. */
|
/* Replace unc as desired. */
|
||||||
if (m_str[0]) {
|
if (m_str[0]) {
|
||||||
auto *p = this->GetWriteBuffer();
|
auto *p = m_write_buffer.Get();
|
||||||
|
|
||||||
/* Replace :/// -> \\ as needed. */
|
/* Replace :/// -> \\ as needed. */
|
||||||
if (auto *sep = std::strstr(p, ":///"); sep != nullptr) {
|
if (auto *sep = std::strstr(p, ":///"); sep != nullptr) {
|
||||||
@@ -250,7 +329,7 @@ namespace ams::fs {
|
|||||||
R_TRY(this->InitializeImpl(path, size));
|
R_TRY(this->InitializeImpl(path, size));
|
||||||
|
|
||||||
/* Set not normalized. */
|
/* Set not normalized. */
|
||||||
m_is_normalized = false;
|
this->SetNotNormalized();
|
||||||
|
|
||||||
/* Perform normalization. */
|
/* Perform normalization. */
|
||||||
fs::PathFlags path_flags;
|
fs::PathFlags path_flags;
|
||||||
@@ -262,16 +341,17 @@ namespace ams::fs {
|
|||||||
/* NOTE: In this case, Nintendo checks is normalized, then sets is normalized, then returns success. */
|
/* NOTE: In this case, Nintendo checks is normalized, then sets is normalized, then returns success. */
|
||||||
/* This seems like a bug. */
|
/* This seems like a bug. */
|
||||||
size_t dummy;
|
size_t dummy;
|
||||||
R_TRY(PathFormatter::IsNormalized(std::addressof(m_is_normalized), std::addressof(dummy), m_str));
|
bool normalized;
|
||||||
|
R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str));
|
||||||
|
|
||||||
m_is_normalized = true;
|
this->SetNormalized();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normalize. */
|
/* Normalize. */
|
||||||
R_TRY(this->Normalize(path_flags));
|
R_TRY(this->Normalize(path_flags));
|
||||||
|
|
||||||
m_is_normalized = true;
|
this->SetNormalized();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +367,7 @@ namespace ams::fs {
|
|||||||
this->ClearBuffer();
|
this->ClearBuffer();
|
||||||
|
|
||||||
/* Set normalized. */
|
/* Set normalized. */
|
||||||
m_is_normalized = true;
|
this->SetNormalized();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
@@ -323,8 +403,8 @@ namespace ams::fs {
|
|||||||
|
|
||||||
/* Reset our write buffer. */
|
/* Reset our write buffer. */
|
||||||
WriteBuffer old_write_buffer;
|
WriteBuffer old_write_buffer;
|
||||||
if (util::GetReference(m_write_buffer) != nullptr) {
|
if (m_write_buffer.Get() != nullptr) {
|
||||||
old_write_buffer = std::move(util::GetReference(m_write_buffer));
|
old_write_buffer = std::move(m_write_buffer);
|
||||||
this->ClearBuffer();
|
this->ClearBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,9 +412,9 @@ namespace ams::fs {
|
|||||||
R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
|
R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
|
||||||
|
|
||||||
/* Get our write buffer. */
|
/* Get our write buffer. */
|
||||||
auto *dst = this->GetWriteBuffer();
|
auto *dst = m_write_buffer.Get();
|
||||||
if (old_write_buffer != nullptr && cur_len > 0) {
|
if (old_write_buffer.Get() != nullptr && cur_len > 0) {
|
||||||
util::Strlcpy<char>(dst, old_write_buffer.get(), cur_len + 1);
|
util::Strlcpy<char>(dst, old_write_buffer.Get(), cur_len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add separator. */
|
/* Add separator. */
|
||||||
@@ -375,15 +455,15 @@ namespace ams::fs {
|
|||||||
|
|
||||||
Result RemoveChild() {
|
Result RemoveChild() {
|
||||||
/* If we don't have a write-buffer, ensure that we have one. */
|
/* If we don't have a write-buffer, ensure that we have one. */
|
||||||
if (util::GetReference(m_write_buffer) == nullptr) {
|
if (m_write_buffer.Get() == nullptr) {
|
||||||
if (const auto len = std::strlen(m_str); len > 0) {
|
if (const auto len = std::strlen(m_str); len > 0) {
|
||||||
R_TRY(this->Preallocate(len));
|
R_TRY(this->Preallocate(len));
|
||||||
util::Strlcpy<char>(util::GetReference(m_write_buffer).get(), m_str, len + 1);
|
util::Strlcpy<char>(m_write_buffer.Get(), m_str, len + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that it's possible for us to remove a child. */
|
/* Check that it's possible for us to remove a child. */
|
||||||
auto *p = this->GetWriteBuffer();
|
auto *p = m_write_buffer.Get();
|
||||||
s32 len = std::strlen(p);
|
s32 len = std::strlen(p);
|
||||||
R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), fs::ResultNotImplemented());
|
R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), fs::ResultNotImplemented());
|
||||||
|
|
||||||
@@ -413,7 +493,7 @@ namespace ams::fs {
|
|||||||
|
|
||||||
Result Normalize(const PathFlags &flags) {
|
Result Normalize(const PathFlags &flags) {
|
||||||
/* If we're already normalized, nothing to do. */
|
/* If we're already normalized, nothing to do. */
|
||||||
R_SUCCEED_IF(m_is_normalized);
|
R_SUCCEED_IF(this->IsNormalized());
|
||||||
|
|
||||||
/* Check if we're normalized. */
|
/* Check if we're normalized. */
|
||||||
bool normalized;
|
bool normalized;
|
||||||
@@ -423,7 +503,7 @@ namespace ams::fs {
|
|||||||
/* If we're not normalized, normalize. */
|
/* If we're not normalized, normalize. */
|
||||||
if (!normalized) {
|
if (!normalized) {
|
||||||
/* Determine necessary buffer length. */
|
/* Determine necessary buffer length. */
|
||||||
auto len = m_write_buffer_length;
|
auto len = m_write_buffer.GetLength();
|
||||||
if (flags.IsRelativePathAllowed() && fs::IsPathRelative(m_str)) {
|
if (flags.IsRelativePathAllowed() && fs::IsPathRelative(m_str)) {
|
||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
@@ -433,57 +513,59 @@ namespace ams::fs {
|
|||||||
|
|
||||||
/* Allocate a new buffer. */
|
/* Allocate a new buffer. */
|
||||||
const size_t size = util::AlignUp(len, WriteBufferAlignmentLength);
|
const size_t size = util::AlignUp(len, WriteBufferAlignmentLength);
|
||||||
auto buf = fs::impl::MakeUnique<char[]>(size);
|
auto buf = WriteBuffer::Make(size);
|
||||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||||
|
|
||||||
/* Normalize into it. */
|
/* Normalize into it. */
|
||||||
R_TRY(PathFormatter::Normalize(buf.get(), size, util::GetReference(m_write_buffer).get(), m_write_buffer_length, flags));
|
R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(), m_write_buffer.GetLength(), flags));
|
||||||
|
|
||||||
/* Set the normalized buffer as our buffer. */
|
/* Set the normalized buffer as our buffer. */
|
||||||
this->SetModifiableBuffer(std::move(buf), size);
|
this->SetModifiableBuffer(std::move(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set normalized. */
|
/* Set normalized. */
|
||||||
m_is_normalized = true;
|
this->SetNormalized();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void ClearBuffer() {
|
void ClearBuffer() {
|
||||||
util::GetReference(m_write_buffer).reset();
|
m_write_buffer.ResetBuffer();
|
||||||
m_write_buffer_length = 0;
|
|
||||||
m_str = EmptyPath;
|
m_str = EmptyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetModifiableBuffer(WriteBuffer &&buffer, size_t size) {
|
void SetModifiableBuffer(WriteBuffer &&buffer) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(buffer.get() != nullptr);
|
AMS_ASSERT(buffer.Get() != nullptr);
|
||||||
AMS_ASSERT(size > 0);
|
AMS_ASSERT(buffer.GetLength() > 0);
|
||||||
AMS_ASSERT(util::IsAligned(size, WriteBufferAlignmentLength));
|
AMS_ASSERT(util::IsAligned(buffer.GetLength(), WriteBufferAlignmentLength));
|
||||||
|
|
||||||
|
/* Get whether we're normalized. */
|
||||||
|
if (m_write_buffer.IsNormalized()) {
|
||||||
|
buffer.SetNormalized();
|
||||||
|
} else {
|
||||||
|
buffer.SetNotNormalized();
|
||||||
|
}
|
||||||
|
|
||||||
/* Set write buffer. */
|
/* Set write buffer. */
|
||||||
util::GetReference(m_write_buffer) = std::move(buffer);
|
m_write_buffer = std::move(buffer);
|
||||||
m_write_buffer_length = size;
|
m_str = m_write_buffer.Get();
|
||||||
m_str = util::GetReference(m_write_buffer).get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void SetReadOnlyBuffer(const char *buffer) {
|
constexpr void SetReadOnlyBuffer(const char *buffer) {
|
||||||
m_str = buffer;
|
m_str = buffer;
|
||||||
if (!std::is_constant_evaluated()) {
|
m_write_buffer.ResetBuffer();
|
||||||
util::GetReference(m_write_buffer) = nullptr;
|
|
||||||
m_write_buffer_length = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Preallocate(size_t length) {
|
Result Preallocate(size_t length) {
|
||||||
/* Allocate additional space, if needed. */
|
/* Allocate additional space, if needed. */
|
||||||
if (length > m_write_buffer_length) {
|
if (length > m_write_buffer.GetLength()) {
|
||||||
/* Allocate buffer. */
|
/* Allocate buffer. */
|
||||||
const size_t size = util::AlignUp(length, WriteBufferAlignmentLength);
|
const size_t size = util::AlignUp(length, WriteBufferAlignmentLength);
|
||||||
auto buf = fs::impl::MakeUnique<char[]>(size);
|
auto buf = WriteBuffer::Make(size);
|
||||||
R_UNLESS(buf != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
R_UNLESS(buf.Get() != nullptr, fs::ResultAllocationMemoryFailedMakeUnique());
|
||||||
|
|
||||||
/* Set write buffer. */
|
/* Set write buffer. */
|
||||||
this->SetModifiableBuffer(std::move(buf), size);
|
this->SetModifiableBuffer(std::move(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@@ -495,7 +577,7 @@ namespace ams::fs {
|
|||||||
R_TRY(this->Preallocate(size + 1));
|
R_TRY(this->Preallocate(size + 1));
|
||||||
|
|
||||||
/* Copy the path. */
|
/* Copy the path. */
|
||||||
const size_t copied = util::Strlcpy<char>(this->GetWriteBuffer(), path, size + 1);
|
const size_t copied = util::Strlcpy<char>(m_write_buffer.Get(), path, size + 1);
|
||||||
R_UNLESS(copied >= size, fs::ResultUnexpectedInPathA());
|
R_UNLESS(copied >= size, fs::ResultUnexpectedInPathA());
|
||||||
} else {
|
} else {
|
||||||
/* We can just clear the buffer. */
|
/* We can just clear the buffer. */
|
||||||
@@ -505,14 +587,20 @@ namespace ams::fs {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
char *GetWriteBuffer() {
|
constexpr char *GetWriteBuffer() {
|
||||||
AMS_ASSERT(util::GetReference(m_write_buffer) != nullptr);
|
AMS_ASSERT(m_write_buffer.Get() != nullptr);
|
||||||
return util::GetReference(m_write_buffer).get();
|
return m_write_buffer.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetWriteBufferLength() const {
|
constexpr ALWAYS_INLINE size_t GetWriteBufferLength() const {
|
||||||
return m_write_buffer_length;
|
return m_write_buffer.GetLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE bool IsNormalized() const { return m_write_buffer.IsNormalized(); }
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE void SetNormalized() { m_write_buffer.SetNormalized(); }
|
||||||
|
|
||||||
|
constexpr ALWAYS_INLINE void SetNotNormalized() { m_write_buffer.SetNotNormalized(); }
|
||||||
public:
|
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 std::strcmp(this->GetString(), rhs.GetString()) == 0; }
|
||||||
ALWAYS_INLINE bool operator!=(const fs::Path &rhs) const { return !(*this == rhs); }
|
ALWAYS_INLINE bool operator!=(const fs::Path &rhs) const { return !(*this == rhs); }
|
||||||
@@ -579,4 +667,9 @@ namespace ams::fs {
|
|||||||
R_RETURN(SetUpFixedPath(out, buf));
|
R_RETURN(SetUpFixedPath(out, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr inline bool IsWindowsDriveRootPath(const fs::Path &path) {
|
||||||
|
const char * const str = path.GetString();
|
||||||
|
return fs::IsWindowsDrive(str) && (str[2] == StringTraits::DirectorySeparator || str[2] == StringTraits::AlternateDirectorySeparator) && str[3] == StringTraits::NullTerminator;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
namespace StringTraits {
|
namespace StringTraits {
|
||||||
|
|
||||||
constexpr inline char DirectorySeparator = '/';
|
constexpr inline char DirectorySeparator = '/';
|
||||||
@@ -618,7 +619,7 @@ namespace ams::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr ALWAYS_INLINE Result SkipMountName(const char **out, size_t *out_len, const char *path) {
|
static constexpr ALWAYS_INLINE Result SkipMountName(const char **out, size_t *out_len, const char *path) {
|
||||||
return ParseMountName(out, out_len, nullptr, 0, path);
|
R_RETURN(ParseMountName(out, out_len, nullptr, 0, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr Result ParseMountName(const char **out, size_t *out_len, char *out_mount_name, size_t out_mount_name_buffer_size, const char *path) {
|
static constexpr Result ParseMountName(const char **out, size_t *out_len, char *out_mount_name, size_t out_mount_name_buffer_size, const char *path) {
|
||||||
@@ -683,7 +684,7 @@ namespace ams::fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr ALWAYS_INLINE Result SkipRelativeDotPath(const char **out, size_t *out_len, const char *path) {
|
static constexpr ALWAYS_INLINE Result SkipRelativeDotPath(const char **out, size_t *out_len, const char *path) {
|
||||||
return ParseRelativeDotPath(out, out_len, nullptr, 0, path);
|
R_RETURN(ParseRelativeDotPath(out, out_len, nullptr, 0, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr Result ParseRelativeDotPath(const char **out, size_t *out_len, char *out_relative, size_t out_relative_buffer_size, const char *path) {
|
static constexpr Result ParseRelativeDotPath(const char **out, size_t *out_len, char *out_relative, size_t out_relative_buffer_size, const char *path) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum Priority {
|
enum Priority {
|
||||||
Priority_Realtime = 0,
|
Priority_Realtime = 0,
|
||||||
Priority_Normal = 1,
|
Priority_Normal = 1,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
struct ProgramIndexMapInfo {
|
struct ProgramIndexMapInfo {
|
||||||
ncm::ProgramId program_id;
|
ncm::ProgramId program_id;
|
||||||
ncm::ProgramId base_program_id;
|
ncm::ProgramId base_program_id;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
struct QueryRangeInfo {
|
struct QueryRangeInfo {
|
||||||
s32 aes_ctr_key_type;
|
s32 aes_ctr_key_type;
|
||||||
s32 speed_emulation_type;
|
s32 speed_emulation_type;
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class ReadOnlyFile : public fsa::IFile, public impl::Newable {
|
class ReadOnlyFile : public fsa::IFile, public impl::Newable {
|
||||||
@@ -34,15 +36,15 @@ namespace ams::fs {
|
|||||||
virtual ~ReadOnlyFile() { /* ... */ }
|
virtual ~ReadOnlyFile() { /* ... */ }
|
||||||
private:
|
private:
|
||||||
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
||||||
return m_base_file->Read(out, offset, buffer, size, option);
|
R_RETURN(m_base_file->Read(out, offset, buffer, size, option));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetSize(s64 *out) override final {
|
virtual Result DoGetSize(s64 *out) override final {
|
||||||
return m_base_file->GetSize(out);
|
R_RETURN(m_base_file->GetSize(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoFlush() override final {
|
virtual Result DoFlush() override final {
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||||
@@ -52,21 +54,21 @@ namespace ams::fs {
|
|||||||
AMS_ASSERT(!need_append);
|
AMS_ASSERT(!need_append);
|
||||||
|
|
||||||
AMS_UNUSED(buffer);
|
AMS_UNUSED(buffer);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFile();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoSetSize(s64 size) override final {
|
virtual Result DoSetSize(s64 size) override final {
|
||||||
R_TRY(this->DrySetSize(size, fs::OpenMode_Read));
|
R_TRY(this->DrySetSize(size, fs::OpenMode_Read));
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFile();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
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) {
|
switch (op_id) {
|
||||||
case OperationId::Invalidate:
|
case OperationId::Invalidate:
|
||||||
case OperationId::QueryRange:
|
case OperationId::QueryRange:
|
||||||
return m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
|
R_RETURN(m_base_file->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||||
default:
|
default:
|
||||||
return fs::ResultUnsupportedOperateRangeForReadOnlyFile();
|
R_THROW(fs::ResultUnsupportedOperateRangeForReadOnlyFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@@ -98,74 +100,73 @@ namespace ams::fs {
|
|||||||
R_UNLESS(read_only_file != nullptr, fs::ResultAllocationMemoryFailedInReadOnlyFileSystemA());
|
R_UNLESS(read_only_file != nullptr, fs::ResultAllocationMemoryFailedInReadOnlyFileSystemA());
|
||||||
|
|
||||||
*out_file = std::move(read_only_file);
|
*out_file = std::move(read_only_file);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
|
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
|
||||||
return m_base_fs->OpenDirectory(out_dir, path, mode);
|
R_RETURN(m_base_fs->OpenDirectory(out_dir, path, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
|
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
|
||||||
return m_base_fs->GetEntryType(out, path);
|
R_RETURN(m_base_fs->GetEntryType(out, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCommit() override final {
|
virtual Result DoCommit() override final {
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
|
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
|
||||||
AMS_UNUSED(path, size, flags);
|
AMS_UNUSED(path, size, flags);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
||||||
AMS_UNUSED(path);
|
AMS_UNUSED(path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
||||||
AMS_UNUSED(path);
|
AMS_UNUSED(path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
||||||
AMS_UNUSED(path);
|
AMS_UNUSED(path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
||||||
AMS_UNUSED(path);
|
AMS_UNUSED(path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
|
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||||
AMS_UNUSED(old_path, new_path);
|
AMS_UNUSED(old_path, new_path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
|
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
|
||||||
AMS_UNUSED(old_path, new_path);
|
AMS_UNUSED(old_path, new_path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
||||||
AMS_UNUSED(path);
|
AMS_UNUSED(path);
|
||||||
return fs::ResultUnsupportedWriteForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedWriteForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||||
AMS_UNUSED(out, path);
|
R_RETURN(m_base_fs->GetFreeSpaceSize(out, path));
|
||||||
return fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||||
AMS_UNUSED(out, path);
|
AMS_UNUSED(out, path);
|
||||||
return fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCommitProvisionally(s64 counter) override final {
|
virtual Result DoCommitProvisionally(s64 counter) override final {
|
||||||
AMS_UNUSED(counter);
|
AMS_UNUSED(counter);
|
||||||
return fs::ResultUnsupportedGetTotalSpaceSizeForReadOnlyFileSystem();
|
R_THROW(fs::ResultUnsupportedCommitProvisionallyForReadOnlyFileSystem());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,23 +35,23 @@ namespace ams::fs {
|
|||||||
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
|
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
|
||||||
public:
|
public:
|
||||||
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
virtual Result DoRead(size_t *out, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) override final {
|
||||||
return fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out);
|
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer, size, option._value, out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetSize(s64 *out) override final {
|
virtual Result DoGetSize(s64 *out) override final {
|
||||||
return fsFileGetSize(std::addressof(m_base_file), out);
|
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoFlush() override final {
|
virtual Result DoFlush() override final {
|
||||||
return fsFileFlush(std::addressof(m_base_file));
|
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
virtual Result DoWrite(s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) override final {
|
||||||
return fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value);
|
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer, size, option._value));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoSetSize(s64 size) override final {
|
virtual Result DoSetSize(s64 size) override final {
|
||||||
return fsFileSetSize(std::addressof(m_base_file), size);
|
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoOperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override final {
|
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(op_id == OperationId::QueryRange, fs::ResultUnsupportedOperateRangeForFileServiceObjectAdapter());
|
||||||
R_UNLESS(dst_size == sizeof(FileQueryRangeInfo), fs::ResultInvalidSize());
|
R_UNLESS(dst_size == sizeof(FileQueryRangeInfo), fs::ResultInvalidSize());
|
||||||
|
|
||||||
return fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst));
|
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(dst)));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
|
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
|
||||||
@@ -80,11 +80,11 @@ namespace ams::fs {
|
|||||||
public:
|
public:
|
||||||
virtual Result DoRead(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) override final {
|
virtual Result DoRead(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries) override final {
|
||||||
static_assert(sizeof(*out_entries) == sizeof(::FsDirectoryEntry));
|
static_assert(sizeof(*out_entries) == sizeof(::FsDirectoryEntry));
|
||||||
return fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries));
|
R_RETURN(fsDirRead(std::addressof(m_base_dir), out_count, max_entries, reinterpret_cast<::FsDirectoryEntry *>(out_entries)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetEntryCount(s64 *out) override final {
|
virtual Result DoGetEntryCount(s64 *out) override final {
|
||||||
return fsDirGetEntryCount(std::addressof(m_base_dir), out);
|
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual sf::cmif::DomainObjectId GetDomainObjectId() const override final {
|
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 {
|
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsCreateFile(std::addressof(m_base_fs), sf_path.str, size, flags);
|
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), sf_path.str, size, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
virtual Result DoDeleteFile(const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsDeleteFile(std::addressof(m_base_fs), sf_path.str);
|
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
virtual Result DoCreateDirectory(const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsCreateDirectory(std::addressof(m_base_fs), sf_path.str);
|
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
virtual Result DoDeleteDirectory(const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsDeleteDirectory(std::addressof(m_base_fs), sf_path.str);
|
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), sf_path.str);
|
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override final {
|
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;
|
fssrv::sf::Path new_sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
|
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
|
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
|
||||||
return fsFsRenameFile(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str);
|
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override final {
|
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;
|
fssrv::sf::Path new_sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
|
R_TRY(GetPathForServiceObject(std::addressof(old_sf_path), old_path));
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
|
R_TRY(GetPathForServiceObject(std::addressof(new_sf_path), new_path));
|
||||||
return fsFsRenameDirectory(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str);
|
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_sf_path.str, new_sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetEntryType(DirectoryEntryType *out, const fs::Path &path) override final {
|
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));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
|
|
||||||
static_assert(sizeof(::FsDirEntryType) == sizeof(DirectoryEntryType));
|
static_assert(sizeof(::FsDirEntryType) == sizeof(DirectoryEntryType));
|
||||||
return fsFsGetEntryType(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsDirEntryType *>(out));
|
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsDirEntryType *>(out)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoOpenFile(std::unique_ptr<fsa::IFile> *out_file, const fs::Path &path, OpenMode mode) override final {
|
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());
|
R_UNLESS(file != nullptr, fs::ResultAllocationMemoryFailedNew());
|
||||||
|
|
||||||
*out_file = std::move(file);
|
*out_file = std::move(file);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoOpenDirectory(std::unique_ptr<fsa::IDirectory> *out_dir, const fs::Path &path, OpenDirectoryMode mode) override final {
|
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());
|
R_UNLESS(dir != nullptr, fs::ResultAllocationMemoryFailedNew());
|
||||||
|
|
||||||
*out_dir = std::move(dir);
|
*out_dir = std::move(dir);
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCommit() override final {
|
virtual Result DoCommit() override final {
|
||||||
return fsFsCommit(std::addressof(m_base_fs));
|
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out);
|
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), sf_path.str, out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out);
|
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), sf_path.str, out));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str);
|
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), sf_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoGetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) override final {
|
virtual Result DoGetFileTimeStampRaw(FileTimeStampRaw *out, const fs::Path &path) override final {
|
||||||
fssrv::sf::Path sf_path;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
static_assert(sizeof(FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
||||||
return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out));
|
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), sf_path.str, reinterpret_cast<::FsTimeStampRaw *>(out)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result DoQueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const fs::Path &path) override final {
|
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;
|
fssrv::sf::Path sf_path;
|
||||||
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
R_TRY(GetPathForServiceObject(std::addressof(sf_path), path));
|
||||||
return fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast<FsFileSystemQueryId>(query));
|
R_RETURN(fsFsQueryEntry(std::addressof(m_base_fs), dst, dst_size, src, src_size, sf_path.str, static_cast<FsFileSystemQueryId>(query)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,29 +32,29 @@ namespace ams::fs {
|
|||||||
virtual ~RemoteStorage() { fsStorageClose(std::addressof(m_base_storage)); }
|
virtual ~RemoteStorage() { fsStorageClose(std::addressof(m_base_storage)); }
|
||||||
public:
|
public:
|
||||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||||
return fsStorageRead(std::addressof(m_base_storage), offset, buffer, size);
|
R_RETURN(fsStorageRead(std::addressof(m_base_storage), offset, buffer, size));
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||||
return fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size);
|
R_RETURN(fsStorageWrite(std::addressof(m_base_storage), offset, buffer, size));
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
return fsStorageFlush(std::addressof(m_base_storage));
|
R_RETURN(fsStorageFlush(std::addressof(m_base_storage)));
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out_size) override {
|
virtual Result GetSize(s64 *out_size) override {
|
||||||
return fsStorageGetSize(std::addressof(m_base_storage), out_size);
|
R_RETURN(fsStorageGetSize(std::addressof(m_base_storage), out_size));
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
return fsStorageSetSize(std::addressof(m_base_storage), size);
|
R_RETURN(fsStorageSetSize(std::addressof(m_base_storage), size));
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
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? */
|
/* TODO: How to deal with this? */
|
||||||
AMS_UNUSED(dst, dst_size, op_id, offset, size, src, src_size);
|
AMS_UNUSED(dst, dst_size, op_id, offset, size, src, src_size);
|
||||||
return fs::ResultUnsupportedOperation();
|
R_THROW(fs::ResultUnsupportedOperation());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
void SetEnabledAutoAbort(bool enabled);
|
void SetEnabledAutoAbort(bool enabled);
|
||||||
void SetResultHandledByApplication(bool application);
|
void SetResultHandledByApplication(bool application);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
union RightsId {
|
union RightsId {
|
||||||
u8 data[0x10];
|
u8 data[0x10];
|
||||||
u64 data64[2];
|
u64 data64[2];
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class RomFsFileSystem : public fsa::IFileSystem, public impl::Newable {
|
class RomFsFileSystem : public fsa::IFileSystem, public impl::Newable {
|
||||||
NON_COPYABLE(RomFsFileSystem);
|
NON_COPYABLE(RomFsFileSystem);
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
Result DeleteSaveData(SaveDataId id);
|
Result DeleteSaveData(SaveDataId id);
|
||||||
Result DeleteSaveData(SaveDataSpaceId space_id, SaveDataId id);
|
Result DeleteSaveData(SaveDataSpaceId space_id, SaveDataId id);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
Result CommitSaveData(const char *path);
|
Result CommitSaveData(const char *path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
using SaveDataId = u64;
|
using SaveDataId = u64;
|
||||||
using SystemSaveDataId = u64;
|
using SystemSaveDataId = u64;
|
||||||
using SystemBcatSaveDataId = SystemSaveDataId;
|
using SystemBcatSaveDataId = SystemSaveDataId;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IEventNotifier;
|
class IEventNotifier;
|
||||||
|
|
||||||
struct EncryptionSeed {
|
struct EncryptionSeed {
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/fs/fs_common.hpp>
|
|
||||||
#include <stratosphere/fs/impl/fs_newable.hpp>
|
|
||||||
#include <stratosphere/fs/fsa/fs_ifile.hpp>
|
|
||||||
#include <stratosphere/fs/fsa/fs_idirectory.hpp>
|
|
||||||
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
|
|
||||||
|
|
||||||
namespace ams::fs {
|
|
||||||
|
|
||||||
class SharedFileSystemHolder : public fsa::IFileSystem, public impl::Newable {
|
|
||||||
NON_COPYABLE(SharedFileSystemHolder);
|
|
||||||
NON_MOVEABLE(SharedFileSystemHolder);
|
|
||||||
private:
|
|
||||||
std::shared_ptr<fsa::IFileSystem> m_fs;
|
|
||||||
public:
|
|
||||||
SharedFileSystemHolder(std::shared_ptr<fsa::IFileSystem> f) : m_fs(std::move(f)) { /* ... */ }
|
|
||||||
public:
|
|
||||||
virtual Result DoCreateFile(const fs::Path &path, s64 size, int flags) override { return m_fs->CreateFile(path, size, flags); }
|
|
||||||
virtual Result DoDeleteFile(const fs::Path &path) override { return m_fs->DeleteFile(path); }
|
|
||||||
virtual Result DoCreateDirectory(const fs::Path &path) override { return m_fs->CreateDirectory(path); }
|
|
||||||
virtual Result DoDeleteDirectory(const fs::Path &path) override { return m_fs->DeleteDirectory(path); }
|
|
||||||
virtual Result DoDeleteDirectoryRecursively(const fs::Path &path) override { return m_fs->DeleteDirectoryRecursively(path); }
|
|
||||||
virtual Result DoRenameFile(const fs::Path &old_path, const fs::Path &new_path) override { return m_fs->RenameFile(old_path, new_path); }
|
|
||||||
virtual Result DoRenameDirectory(const fs::Path &old_path, const fs::Path &new_path) override { return m_fs->RenameDirectory(old_path, new_path); }
|
|
||||||
virtual Result DoGetEntryType(fs::DirectoryEntryType *out, const fs::Path &path) override { return m_fs->GetEntryType(out, path); }
|
|
||||||
virtual Result DoOpenFile(std::unique_ptr<fs::fsa::IFile> *out_file, const fs::Path &path, fs::OpenMode mode) override { return m_fs->OpenFile(out_file, path, mode); }
|
|
||||||
virtual Result DoOpenDirectory(std::unique_ptr<fs::fsa::IDirectory> *out_dir, const fs::Path &path, fs::OpenDirectoryMode mode) override { return m_fs->OpenDirectory(out_dir, path, mode); }
|
|
||||||
virtual Result DoCommit() override { return m_fs->Commit(); }
|
|
||||||
virtual Result DoGetFreeSpaceSize(s64 *out, const fs::Path &path) override { return m_fs->GetFreeSpaceSize(out, path); }
|
|
||||||
virtual Result DoGetTotalSpaceSize(s64 *out, const fs::Path &path) override { return m_fs->GetTotalSpaceSize(out, path); }
|
|
||||||
virtual Result DoCleanDirectoryRecursively(const fs::Path &path) override { return m_fs->CleanDirectoryRecursively(path); }
|
|
||||||
|
|
||||||
/* These aren't accessible as commands. */
|
|
||||||
virtual Result DoCommitProvisionally(s64 counter) override { return m_fs->CommitProvisionally(counter); }
|
|
||||||
virtual Result DoRollback() override { return m_fs->Rollback(); }
|
|
||||||
virtual Result DoFlush() override { return m_fs->Flush(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
bool IsSignedSystemPartitionOnSdCardValid(const char *system_root_path);
|
bool IsSignedSystemPartitionOnSdCardValid(const char *system_root_path);
|
||||||
bool IsSignedSystemPartitionOnSdCardValidDeprecated();
|
bool IsSignedSystemPartitionOnSdCardValidDeprecated();
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum class SpeedEmulationMode {
|
enum class SpeedEmulationMode {
|
||||||
None = 0,
|
None = 0,
|
||||||
Faster = 1,
|
Faster = 1,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum StorageType : s32 {
|
enum StorageType : s32 {
|
||||||
StorageType_SaveData = 0,
|
StorageType_SaveData = 0,
|
||||||
StorageType_RomFs = 1,
|
StorageType_RomFs = 1,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class SubStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
class SubStorage : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IStorage> m_shared_base_storage;
|
std::shared_ptr<IStorage> m_shared_base_storage;
|
||||||
@@ -74,41 +75,42 @@ namespace ams::fs {
|
|||||||
public:
|
public:
|
||||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||||
/* Ensure we're initialized. */
|
/* Ensure we're initialized. */
|
||||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||||
|
|
||||||
/* Succeed immediately on zero-sized operation. */
|
/* Succeed immediately on zero-sized operation. */
|
||||||
R_SUCCEED_IF(size == 0);
|
R_SUCCEED_IF(size == 0);
|
||||||
|
|
||||||
|
|
||||||
/* Validate arguments and read. */
|
/* Validate arguments and read. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
return m_base_storage->Read(m_offset + offset, buffer, size);
|
R_RETURN(m_base_storage->Read(m_offset + offset, buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
virtual Result Write(s64 offset, const void *buffer, size_t size) override{
|
||||||
/* Ensure we're initialized. */
|
/* Ensure we're initialized. */
|
||||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||||
|
|
||||||
/* Succeed immediately on zero-sized operation. */
|
/* Succeed immediately on zero-sized operation. */
|
||||||
R_SUCCEED_IF(size == 0);
|
R_SUCCEED_IF(size == 0);
|
||||||
|
|
||||||
/* Validate arguments and write. */
|
/* Validate arguments and write. */
|
||||||
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(IStorage::CheckAccessRange(offset, size, m_size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckAccessRange(offset, size, m_size));
|
||||||
return m_base_storage->Write(m_offset + offset, buffer, size);
|
R_RETURN(m_base_storage->Write(m_offset + offset, buffer, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result Flush() override {
|
virtual Result Flush() override {
|
||||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||||
return m_base_storage->Flush();
|
R_RETURN(m_base_storage->Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result SetSize(s64 size) override {
|
virtual Result SetSize(s64 size) override {
|
||||||
/* Ensure we're initialized and validate arguments. */
|
/* Ensure we're initialized and validate arguments. */
|
||||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||||
R_UNLESS(m_resizable, fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
|
R_UNLESS(m_resizable, fs::ResultUnsupportedSetSizeForNotResizableSubStorage());
|
||||||
R_UNLESS(IStorage::CheckOffsetAndSize(m_offset, size), fs::ResultInvalidSize());
|
|
||||||
|
R_TRY(IStorage::CheckOffsetAndSize(m_offset, size));
|
||||||
|
|
||||||
/* Ensure that we're allowed to set size. */
|
/* Ensure that we're allowed to set size. */
|
||||||
s64 cur_size;
|
s64 cur_size;
|
||||||
@@ -119,7 +121,7 @@ namespace ams::fs {
|
|||||||
R_TRY(m_base_storage->SetSize(m_offset + size));
|
R_TRY(m_base_storage->SetSize(m_offset + size));
|
||||||
|
|
||||||
m_size = size;
|
m_size = size;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result GetSize(s64 *out) override {
|
virtual Result GetSize(s64 *out) override {
|
||||||
@@ -127,19 +129,24 @@ namespace ams::fs {
|
|||||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||||
|
|
||||||
*out = m_size;
|
*out = m_size;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Result OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
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. */
|
/* Ensure we're initialized. */
|
||||||
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
R_UNLESS(this->IsValid(), fs::ResultNotInitialized());
|
||||||
|
|
||||||
/* Succeed immediately on zero-sized operation. */
|
/* If we're not invalidating, sanity check arguments. */
|
||||||
R_SUCCEED_IF(size == 0);
|
if (op_id != fs::OperationId::Invalidate) {
|
||||||
|
/* Succeed immediately on zero-sized operation other than invalidate. */
|
||||||
|
R_SUCCEED_IF(size == 0);
|
||||||
|
|
||||||
/* Validate arguments and operate. */
|
/* Check access extents. */
|
||||||
R_UNLESS(IStorage::CheckOffsetAndSize(offset, size), fs::ResultOutOfRange());
|
R_TRY(IStorage::CheckOffsetAndSize(offset, size));
|
||||||
return m_base_storage->OperateRange(dst, dst_size, op_id, m_offset + offset, size, src, src_size);
|
}
|
||||||
|
|
||||||
|
/* Perform the operation. */
|
||||||
|
R_RETURN(m_base_storage->OperateRange(dst, dst_size, op_id, m_offset + offset, size, src, src_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
using IStorage::OperateRange;
|
using IStorage::OperateRange;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
Result QueryMountSystemDataCacheSize(size_t *out, ncm::SystemDataId data_id);
|
Result QueryMountSystemDataCacheSize(size_t *out, ncm::SystemDataId data_id);
|
||||||
|
|
||||||
Result MountSystemData(const char *name, ncm::SystemDataId data_id);
|
Result MountSystemData(const char *name, ncm::SystemDataId data_id);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs {
|
namespace ams::fs {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
void DisableAutoSaveDataCreation();
|
void DisableAutoSaveDataCreation();
|
||||||
|
|
||||||
Result CreateSystemSaveData(SystemSaveDataId save_id, s64 size, s64 journal_size, u32 flags);
|
Result CreateSystemSaveData(SystemSaveDataId save_id, s64 size, s64 journal_size, u32 flags);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::fsa {
|
namespace ams::fs::fsa {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IDirectory {
|
class IDirectory {
|
||||||
public:
|
public:
|
||||||
virtual ~IDirectory() { /* ... */ }
|
virtual ~IDirectory() { /* ... */ }
|
||||||
@@ -28,7 +29,7 @@ namespace ams::fs::fsa {
|
|||||||
R_UNLESS(out_count != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(out_count != nullptr, fs::ResultNullptrArgument());
|
||||||
if (max_entries == 0) {
|
if (max_entries == 0) {
|
||||||
*out_count = 0;
|
*out_count = 0;
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
|
R_UNLESS(out_entries != nullptr, fs::ResultNullptrArgument());
|
||||||
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());
|
R_UNLESS(max_entries > 0, fs::ResultInvalidArgument());
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::fsa {
|
namespace ams::fs::fsa {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IFile;
|
class IFile;
|
||||||
class IDirectory;
|
class IDirectory;
|
||||||
|
|
||||||
@@ -180,4 +181,7 @@ namespace ams::fs::fsa {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept PointerToFileSystem = ::ams::util::RawOrSmartPointerTo<T, ::ams::fs::fsa::IFileSystem>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::fsa {
|
namespace ams::fs::fsa {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class ICommonMountNameGenerator {
|
class ICommonMountNameGenerator {
|
||||||
public:
|
public:
|
||||||
virtual ~ICommonMountNameGenerator() { /* ... */ }
|
virtual ~ICommonMountNameGenerator() { /* ... */ }
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum AccessLogTarget : u32 {
|
enum AccessLogTarget : u32 {
|
||||||
AccessLogTarget_None = (0 << 0),
|
AccessLogTarget_None = (0 << 0),
|
||||||
AccessLogTarget_Application = (1 << 0),
|
AccessLogTarget_Application = (1 << 0),
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
|
|
||||||
/* Delimiting of mount names. */
|
/* Delimiting of mount names. */
|
||||||
constexpr inline const char ReservedMountNamePrefixCharacter = '@';
|
constexpr inline const char ReservedMountNamePrefixCharacter = '@';
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
Result QueryMountDataCacheSize(size_t *out, ncm::DataId data_id, ncm::StorageId storage_id);
|
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);
|
Result MountData(const char *name, ncm::DataId data_id, ncm::StorageId storage_id);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum FileSystemProxyType {
|
enum FileSystemProxyType {
|
||||||
FileSystemProxyType_Code = 0,
|
FileSystemProxyType_Code = 0,
|
||||||
FileSystemProxyType_Rom = 1,
|
FileSystemProxyType_Rom = 1,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
constexpr inline u8 TlsIoPriorityMask = 0x7;
|
constexpr inline u8 TlsIoPriorityMask = 0x7;
|
||||||
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
|
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
fssystem::IHash256GeneratorFactorySelector *GetNcaHashGeneratorFactorySelector();
|
fssystem::IHash256GeneratorFactorySelector *GetNcaHashGeneratorFactorySelector();
|
||||||
fssystem::IHash256GeneratorFactorySelector *GetSaveDataHashGeneratorFactorySelector();
|
fssystem::IHash256GeneratorFactorySelector *GetSaveDataHashGeneratorFactorySelector();
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class Newable {
|
class Newable {
|
||||||
public:
|
public:
|
||||||
static ALWAYS_INLINE void *operator new(size_t size) noexcept {
|
static ALWAYS_INLINE void *operator new(size_t size) noexcept {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
enum TlsIoPriority : u8 {
|
enum TlsIoPriority : u8 {
|
||||||
TlsIoPriority_Normal = 0,
|
TlsIoPriority_Normal = 0,
|
||||||
TlsIoPriority_Realtime = 1,
|
TlsIoPriority_Realtime = 1,
|
||||||
@@ -43,10 +44,10 @@ namespace ams::fs::impl {
|
|||||||
case PriorityRaw_Realtime: *out = TlsIoPriority_Realtime; break;
|
case PriorityRaw_Realtime: *out = TlsIoPriority_Realtime; break;
|
||||||
case PriorityRaw_Low: *out = TlsIoPriority_Low; break;
|
case PriorityRaw_Low: *out = TlsIoPriority_Low; break;
|
||||||
case PriorityRaw_Background: *out = TlsIoPriority_Background; break;
|
case PriorityRaw_Background: *out = TlsIoPriority_Background; break;
|
||||||
default: return fs::ResultInvalidArgument();
|
default: R_THROW(fs::ResultInvalidArgument());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
|
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
|
||||||
@@ -57,10 +58,10 @@ namespace ams::fs::impl {
|
|||||||
case TlsIoPriority_Realtime: *out = PriorityRaw_Realtime; break;
|
case TlsIoPriority_Realtime: *out = PriorityRaw_Realtime; break;
|
||||||
case TlsIoPriority_Low: *out = PriorityRaw_Low; break;
|
case TlsIoPriority_Low: *out = PriorityRaw_Low; break;
|
||||||
case TlsIoPriority_Background: *out = PriorityRaw_Background; break;
|
case TlsIoPriority_Background: *out = PriorityRaw_Background; break;
|
||||||
default: return fs::ResultInvalidArgument();
|
default: R_THROW(fs::ResultInvalidArgument());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u8 GetTlsIoPriority(os::ThreadType *thread) {
|
inline u8 GetTlsIoPriority(os::ThreadType *thread) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
bool IsAbortNeeded(Result result);
|
bool IsAbortNeeded(Result result);
|
||||||
void LogErrorMessage(Result result, const char *function);
|
void LogErrorMessage(Result result, const char *function);
|
||||||
|
|
||||||
|
|||||||
@@ -14,17 +14,20 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere/fs/fs_common.hpp>
|
||||||
|
#include <stratosphere/fs/fs_istorage.hpp>
|
||||||
|
#include <stratosphere/fs/impl/fs_newable.hpp>
|
||||||
|
|
||||||
namespace ams::fs::impl {
|
namespace ams::fs::impl {
|
||||||
|
|
||||||
|
template<typename StorageInterface>
|
||||||
class StorageServiceObjectAdapter : public ::ams::fs::impl::Newable, public ::ams::fs::IStorage {
|
class StorageServiceObjectAdapter : public ::ams::fs::impl::Newable, public ::ams::fs::IStorage {
|
||||||
NON_COPYABLE(StorageServiceObjectAdapter);
|
NON_COPYABLE(StorageServiceObjectAdapter);
|
||||||
NON_MOVEABLE(StorageServiceObjectAdapter);
|
NON_MOVEABLE(StorageServiceObjectAdapter);
|
||||||
private:
|
private:
|
||||||
sf::SharedPointer<fssrv::sf::IStorage> m_x;
|
sf::SharedPointer<StorageInterface> m_x;
|
||||||
public:
|
public:
|
||||||
explicit StorageServiceObjectAdapter(sf::SharedPointer<fssrv::sf::IStorage> &&o) : m_x(o) { /* ... */}
|
explicit StorageServiceObjectAdapter(sf::SharedPointer<StorageInterface> &&o) : m_x(o) { /* ... */}
|
||||||
virtual ~StorageServiceObjectAdapter() { /* ... */ }
|
virtual ~StorageServiceObjectAdapter() { /* ... */ }
|
||||||
public:
|
public:
|
||||||
virtual Result Read(s64 offset, void *buffer, size_t size) override final {
|
virtual Result Read(s64 offset, void *buffer, size_t size) override final {
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::fscreator {
|
namespace ams::fssrv::fscreator {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class LocalFileSystemCreator final : public ILocalFileSystemCreator {
|
class LocalFileSystemCreator final : public ILocalFileSystemCreator {
|
||||||
NON_COPYABLE(LocalFileSystemCreator);
|
NON_COPYABLE(LocalFileSystemCreator);
|
||||||
NON_MOVEABLE(LocalFileSystemCreator);
|
NON_MOVEABLE(LocalFileSystemCreator);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::fscreator {
|
namespace ams::fssrv::fscreator {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class PartitionFileSystemCreator : public IPartitionFileSystemCreator {
|
class PartitionFileSystemCreator : public IPartitionFileSystemCreator {
|
||||||
NON_COPYABLE(PartitionFileSystemCreator);
|
NON_COPYABLE(PartitionFileSystemCreator);
|
||||||
NON_MOVEABLE(PartitionFileSystemCreator);
|
NON_MOVEABLE(PartitionFileSystemCreator);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::fscreator {
|
namespace ams::fssrv::fscreator {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class RomFileSystemCreator : public IRomFileSystemCreator {
|
class RomFileSystemCreator : public IRomFileSystemCreator {
|
||||||
NON_COPYABLE(RomFileSystemCreator);
|
NON_COPYABLE(RomFileSystemCreator);
|
||||||
NON_MOVEABLE(RomFileSystemCreator);
|
NON_MOVEABLE(RomFileSystemCreator);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::fscreator {
|
namespace ams::fssrv::fscreator {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class SubDirectoryFileSystemCreator final : public ISubDirectoryFileSystemCreator {
|
class SubDirectoryFileSystemCreator final : public ISubDirectoryFileSystemCreator {
|
||||||
NON_COPYABLE(SubDirectoryFileSystemCreator);
|
NON_COPYABLE(SubDirectoryFileSystemCreator);
|
||||||
NON_MOVEABLE(SubDirectoryFileSystemCreator);
|
NON_MOVEABLE(SubDirectoryFileSystemCreator);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace ams::fssrv {
|
|||||||
class AccessLogServiceImpl;
|
class AccessLogServiceImpl;
|
||||||
class DebugConfigurationServiceImpl;
|
class DebugConfigurationServiceImpl;
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
struct FileSystemProxyConfiguration {
|
struct FileSystemProxyConfiguration {
|
||||||
fscreator::FileSystemCreatorInterfaces *m_fs_creator_interfaces;
|
fscreator::FileSystemCreatorInterfaces *m_fs_creator_interfaces;
|
||||||
BaseStorageServiceImpl *m_base_storage_service_impl;
|
BaseStorageServiceImpl *m_base_storage_service_impl;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace ams::fssrv {
|
|||||||
class NcaFileSystemService;
|
class NcaFileSystemService;
|
||||||
class SaveDataFileSystemService;
|
class SaveDataFileSystemService;
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class FileSystemProxyImpl {
|
class FileSystemProxyImpl {
|
||||||
NON_COPYABLE(FileSystemProxyImpl);
|
NON_COPYABLE(FileSystemProxyImpl);
|
||||||
NON_MOVEABLE(FileSystemProxyImpl);
|
NON_MOVEABLE(FileSystemProxyImpl);
|
||||||
@@ -147,26 +148,27 @@ namespace ams::fssrv {
|
|||||||
static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>);
|
static_assert(sf::IsIFileSystemProxy<FileSystemProxyImpl>);
|
||||||
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);
|
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class InvalidFileSystemProxyImplForLoader {
|
class InvalidFileSystemProxyImplForLoader {
|
||||||
public:
|
public:
|
||||||
Result OpenCodeFileSystemDeprecated(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
|
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);
|
AMS_UNUSED(out_fs, path, program_id);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenCodeFileSystem(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFileSystem>> out_fs, ams::sf::Out<fs::CodeVerificationData> out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id) {
|
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);
|
AMS_UNUSED(out_fs, out_verif, path, program_id);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
|
Result IsArchivedProgram(ams::sf::Out<bool> out, u64 process_id) {
|
||||||
AMS_UNUSED(out, process_id);
|
AMS_UNUSED(out, process_id);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
|
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
|
||||||
AMS_UNUSED(client_pid);
|
AMS_UNUSED(client_pid);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);
|
static_assert(sf::IsIFileSystemProxyForLoader<FileSystemProxyImpl>);
|
||||||
|
|||||||
@@ -49,18 +49,21 @@ namespace ams::fssystem {
|
|||||||
|
|
||||||
namespace ams::fssrv::fscreator {
|
namespace ams::fssrv::fscreator {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IRomFileSystemCreator {
|
class IRomFileSystemCreator {
|
||||||
public:
|
public:
|
||||||
virtual ~IRomFileSystemCreator() { /* ... */ }
|
virtual ~IRomFileSystemCreator() { /* ... */ }
|
||||||
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::IStorage> storage) = 0;
|
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::IStorage> storage) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IPartitionFileSystemCreator {
|
class IPartitionFileSystemCreator {
|
||||||
public:
|
public:
|
||||||
virtual ~IPartitionFileSystemCreator() { /* ... */ }
|
virtual ~IPartitionFileSystemCreator() { /* ... */ }
|
||||||
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::IStorage> storage) = 0;
|
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::IStorage> storage) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class IStorageOnNcaCreator {
|
class IStorageOnNcaCreator {
|
||||||
public:
|
public:
|
||||||
virtual ~IStorageOnNcaCreator() { /* ... */ }
|
virtual ~IStorageOnNcaCreator() { /* ... */ }
|
||||||
@@ -69,6 +72,7 @@ namespace ams::fssrv::fscreator {
|
|||||||
virtual Result CreateNcaReader(std::shared_ptr<fssystem::NcaReader> *out, std::shared_ptr<fs::IStorage> storage) = 0;
|
virtual Result CreateNcaReader(std::shared_ptr<fssystem::NcaReader> *out, std::shared_ptr<fs::IStorage> storage) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class ILocalFileSystemCreator {
|
class ILocalFileSystemCreator {
|
||||||
public:
|
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;
|
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, const fs::Path &path, bool case_sensitive, bool ensure_root, Result on_path_not_found) = 0;
|
||||||
@@ -78,11 +82,13 @@ namespace ams::fssrv::fscreator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class ISubDirectoryFileSystemCreator {
|
class ISubDirectoryFileSystemCreator {
|
||||||
public:
|
public:
|
||||||
virtual Result Create(std::shared_ptr<fs::fsa::IFileSystem> *out, std::shared_ptr<fs::fsa::IFileSystem> base_fs, const fs::Path &path) = 0;
|
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 {
|
struct FileSystemCreatorInterfaces {
|
||||||
ILocalFileSystemCreator *local_fs_creator;
|
ILocalFileSystemCreator *local_fs_creator;
|
||||||
ISubDirectoryFileSystemCreator *subdir_fs_creator;
|
ISubDirectoryFileSystemCreator *subdir_fs_creator;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv {
|
namespace ams::fssrv {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class MemoryResourceFromExpHeap : public ams::MemoryResource {
|
class MemoryResourceFromExpHeap : public ams::MemoryResource {
|
||||||
private:
|
private:
|
||||||
lmem::HeapHandle m_heap_handle;
|
lmem::HeapHandle m_heap_handle;
|
||||||
@@ -41,6 +42,7 @@ namespace ams::fssrv {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class PeakCheckableMemoryResourceFromExpHeap : public ams::MemoryResource {
|
class PeakCheckableMemoryResourceFromExpHeap : public ams::MemoryResource {
|
||||||
private:
|
private:
|
||||||
lmem::HeapHandle m_heap_handle;
|
lmem::HeapHandle m_heap_handle;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace ams::mem {
|
|||||||
|
|
||||||
namespace ams::fssrv {
|
namespace ams::fssrv {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class MemoryResourceFromStandardAllocator : public ams::MemoryResource {
|
class MemoryResourceFromStandardAllocator : public ams::MemoryResource {
|
||||||
private:
|
private:
|
||||||
mem::StandardAllocator *m_allocator;
|
mem::StandardAllocator *m_allocator;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace ams::fssrv {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class NcaFileSystemServiceImpl {
|
class NcaFileSystemServiceImpl {
|
||||||
public:
|
public:
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace ams::fssrv {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class ProgramRegistryImpl {
|
class ProgramRegistryImpl {
|
||||||
NON_COPYABLE(ProgramRegistryImpl);
|
NON_COPYABLE(ProgramRegistryImpl);
|
||||||
NON_MOVEABLE(ProgramRegistryImpl);
|
NON_MOVEABLE(ProgramRegistryImpl);
|
||||||
@@ -45,26 +46,27 @@ namespace ams::fssrv {
|
|||||||
};
|
};
|
||||||
static_assert(sf::IsIProgramRegistry<ProgramRegistryImpl>);
|
static_assert(sf::IsIProgramRegistry<ProgramRegistryImpl>);
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class InvalidProgramRegistryImpl {
|
class InvalidProgramRegistryImpl {
|
||||||
public:
|
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) {
|
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);
|
AMS_UNUSED(process_id, program_id, storage_id, data, data_size, desc, desc_size);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnregisterProgram(u64 process_id) {
|
Result UnregisterProgram(u64 process_id) {
|
||||||
AMS_UNUSED(process_id);
|
AMS_UNUSED(process_id);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
|
Result SetCurrentProcess(const ams::sf::ClientProcessId &client_pid) {
|
||||||
AMS_UNUSED(client_pid);
|
AMS_UNUSED(client_pid);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetEnabledProgramVerification(bool en) {
|
Result SetEnabledProgramVerification(bool en) {
|
||||||
AMS_UNUSED(en);
|
AMS_UNUSED(en);
|
||||||
return fs::ResultPortAcceptableCountLimited();
|
R_THROW(fs::ResultPortAcceptableCountLimited());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(sf::IsIProgramRegistry<InvalidProgramRegistryImpl>);
|
static_assert(sf::IsIProgramRegistry<InvalidProgramRegistryImpl>);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace ams::fssrv {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: Unknown */
|
||||||
class ProgramRegistryServiceImpl {
|
class ProgramRegistryServiceImpl {
|
||||||
public:
|
public:
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace ams::fssrv {
|
|||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
struct Accessibility {
|
struct Accessibility {
|
||||||
u8 value;
|
u8 value;
|
||||||
|
|
||||||
@@ -60,6 +61,7 @@ namespace ams::fssrv::impl {
|
|||||||
Accessibility GetAccessibility() const { return m_accessibility; }
|
Accessibility GetAccessibility() const { return m_accessibility; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class AccessControl {
|
class AccessControl {
|
||||||
public:
|
public:
|
||||||
enum class AccessibilityType : u32 {
|
enum class AccessibilityType : u32 {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
#define AMS_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(HANDLER, _NS_) \
|
#define AMS_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(HANDLER, _NS_) \
|
||||||
HANDLER(CanAbandonAccessFailure, _NS_::AccessFailureResolution) \
|
HANDLER(CanAbandonAccessFailure, _NS_::AccessFailureResolution) \
|
||||||
HANDLER(CanChallengeCardExistence, _NS_::GameCard) \
|
HANDLER(CanChallengeCardExistence, _NS_::GameCard) \
|
||||||
@@ -179,6 +180,7 @@ namespace ams::fssrv::impl {
|
|||||||
HANDLER(CanWriteSaveDataFileSystemExtraDataFlags, _NS_::SaveDataTransferVersion2, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp) \
|
HANDLER(CanWriteSaveDataFileSystemExtraDataFlags, _NS_::SaveDataTransferVersion2, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp) \
|
||||||
HANDLER(CanWriteSaveDataFileSystemExtraDataTimeStamp, _NS_::SaveDataBackUp)
|
HANDLER(CanWriteSaveDataFileSystemExtraDataTimeStamp, _NS_::SaveDataBackUp)
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class AccessControlBits {
|
class AccessControlBits {
|
||||||
public:
|
public:
|
||||||
enum class Bits : u64 {
|
enum class Bits : u64 {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class ExternalKeyEntry : public util::IntrusiveListBaseNode<ExternalKeyEntry>, public ::ams::fs::impl::Newable {
|
class ExternalKeyEntry : public util::IntrusiveListBaseNode<ExternalKeyEntry>, public ::ams::fs::impl::Newable {
|
||||||
private:
|
private:
|
||||||
fs::RightsId m_rights_id;
|
fs::RightsId m_rights_id;
|
||||||
@@ -48,6 +49,7 @@ namespace ams::fssrv::impl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class ExternalKeyManager {
|
class ExternalKeyManager {
|
||||||
NON_COPYABLE(ExternalKeyManager);
|
NON_COPYABLE(ExternalKeyManager);
|
||||||
NON_MOVEABLE(ExternalKeyManager);
|
NON_MOVEABLE(ExternalKeyManager);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
ams::sf::EmplacedRef<fssrv::sf::IFileSystemProxy, fssrv::FileSystemProxyImpl> GetFileSystemProxyServiceObject();
|
ams::sf::EmplacedRef<fssrv::sf::IFileSystemProxy, fssrv::FileSystemProxyImpl> GetFileSystemProxyServiceObject();
|
||||||
|
|
||||||
ams::sf::SharedPointer<fssrv::sf::IProgramRegistry> GetProgramRegistryServiceObject();
|
ams::sf::SharedPointer<fssrv::sf::IProgramRegistry> GetProgramRegistryServiceObject();
|
||||||
|
|||||||
@@ -22,12 +22,14 @@
|
|||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
struct ProgramIndexMapInfoEntry : public ::ams::util::IntrusiveListBaseNode<ProgramIndexMapInfoEntry>, public ::ams::fs::impl::Newable {
|
struct ProgramIndexMapInfoEntry : public ::ams::util::IntrusiveListBaseNode<ProgramIndexMapInfoEntry>, public ::ams::fs::impl::Newable {
|
||||||
ncm::ProgramId program_id;
|
ncm::ProgramId program_id;
|
||||||
ncm::ProgramId base_program_id;
|
ncm::ProgramId base_program_id;
|
||||||
u8 program_index;
|
u8 program_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class ProgramIndexMapInfoManager {
|
class ProgramIndexMapInfoManager {
|
||||||
NON_COPYABLE(ProgramIndexMapInfoManager);
|
NON_COPYABLE(ProgramIndexMapInfoManager);
|
||||||
NON_MOVEABLE(ProgramIndexMapInfoManager);
|
NON_MOVEABLE(ProgramIndexMapInfoManager);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ namespace ams::fssrv::impl {
|
|||||||
|
|
||||||
class FileSystemInterfaceAdapter;
|
class FileSystemInterfaceAdapter;
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class FileInterfaceAdapter {
|
class FileInterfaceAdapter {
|
||||||
NON_COPYABLE(FileInterfaceAdapter);
|
NON_COPYABLE(FileInterfaceAdapter);
|
||||||
NON_MOVEABLE(FileInterfaceAdapter);
|
NON_MOVEABLE(FileInterfaceAdapter);
|
||||||
@@ -60,6 +61,7 @@ namespace ams::fssrv::impl {
|
|||||||
};
|
};
|
||||||
static_assert(fssrv::sf::IsIFile<FileInterfaceAdapter>);
|
static_assert(fssrv::sf::IsIFile<FileInterfaceAdapter>);
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class DirectoryInterfaceAdapter {
|
class DirectoryInterfaceAdapter {
|
||||||
NON_COPYABLE(DirectoryInterfaceAdapter);
|
NON_COPYABLE(DirectoryInterfaceAdapter);
|
||||||
NON_MOVEABLE(DirectoryInterfaceAdapter);
|
NON_MOVEABLE(DirectoryInterfaceAdapter);
|
||||||
@@ -76,6 +78,7 @@ namespace ams::fssrv::impl {
|
|||||||
};
|
};
|
||||||
static_assert(fssrv::sf::IsIDirectory<DirectoryInterfaceAdapter>);
|
static_assert(fssrv::sf::IsIDirectory<DirectoryInterfaceAdapter>);
|
||||||
|
|
||||||
|
/* ACCURATE_TO_VERSION: 13.4.0.0 */
|
||||||
class FileSystemInterfaceAdapter : public ams::sf::ISharedObject {
|
class FileSystemInterfaceAdapter : public ams::sf::ISharedObject {
|
||||||
NON_COPYABLE(FileSystemInterfaceAdapter);
|
NON_COPYABLE(FileSystemInterfaceAdapter);
|
||||||
NON_MOVEABLE(FileSystemInterfaceAdapter);
|
NON_MOVEABLE(FileSystemInterfaceAdapter);
|
||||||
@@ -117,7 +120,7 @@ namespace ams::fssrv::impl {
|
|||||||
Result CleanDirectoryRecursively(const fssrv::sf::Path &path);
|
Result CleanDirectoryRecursively(const fssrv::sf::Path &path);
|
||||||
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path);
|
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path);
|
||||||
|
|
||||||
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
|
Result QueryEntry(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||||
@@ -132,28 +135,28 @@ namespace ams::fssrv::impl {
|
|||||||
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
|
virtual ~RemoteFile() { fsFileClose(std::addressof(m_base_file)); }
|
||||||
public:
|
public:
|
||||||
Result Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option) {
|
Result Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option) {
|
||||||
return fsFileRead(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value, reinterpret_cast<u64 *>(out.GetPointer()));
|
R_RETURN(fsFileRead(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value, reinterpret_cast<u64 *>(out.GetPointer())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size, fs::WriteOption option) {
|
Result Write(s64 offset, const ams::sf::InNonSecureBuffer &buffer, s64 size, fs::WriteOption option) {
|
||||||
return fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value);
|
R_RETURN(fsFileWrite(std::addressof(m_base_file), offset, buffer.GetPointer(), size, option._value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Flush(){
|
Result Flush(){
|
||||||
return fsFileFlush(std::addressof(m_base_file));
|
R_RETURN(fsFileFlush(std::addressof(m_base_file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SetSize(s64 size) {
|
Result SetSize(s64 size) {
|
||||||
return fsFileSetSize(std::addressof(m_base_file), size);
|
R_RETURN(fsFileSetSize(std::addressof(m_base_file), size));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetSize(ams::sf::Out<s64> out) {
|
Result GetSize(ams::sf::Out<s64> out) {
|
||||||
return fsFileGetSize(std::addressof(m_base_file), out.GetPointer());
|
R_RETURN(fsFileGetSize(std::addressof(m_base_file), out.GetPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OperateRange(ams::sf::Out<fs::FileQueryRangeInfo> out, s32 op_id, s64 offset, s64 size) {
|
Result OperateRange(ams::sf::Out<fs::FileQueryRangeInfo> out, s32 op_id, s64 offset, s64 size) {
|
||||||
static_assert(sizeof(::FsRangeInfo) == sizeof(fs::FileQueryRangeInfo));
|
static_assert(sizeof(::FsRangeInfo) == sizeof(fs::FileQueryRangeInfo));
|
||||||
return fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer()));
|
R_RETURN(fsFileOperateRange(std::addressof(m_base_file), static_cast<::FsOperationId>(op_id), offset, size, reinterpret_cast<::FsRangeInfo *>(out.GetPointer())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OperateRangeWithBuffer(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 op_id, s64 offset, s64 size) {
|
Result OperateRangeWithBuffer(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &in_buf, s32 op_id, s64 offset, s64 size) {
|
||||||
@@ -175,11 +178,11 @@ namespace ams::fssrv::impl {
|
|||||||
public:
|
public:
|
||||||
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries) {
|
Result Read(ams::sf::Out<s64> out, const ams::sf::OutBuffer &out_entries) {
|
||||||
static_assert(sizeof(::FsDirectoryEntry) == sizeof(fs::DirectoryEntry));
|
static_assert(sizeof(::FsDirectoryEntry) == sizeof(fs::DirectoryEntry));
|
||||||
return fsDirRead(std::addressof(m_base_dir), out.GetPointer(), out_entries.GetSize() / sizeof(fs::DirectoryEntry), reinterpret_cast<::FsDirectoryEntry *>(out_entries.GetPointer()));
|
R_RETURN(fsDirRead(std::addressof(m_base_dir), out.GetPointer(), out_entries.GetSize() / sizeof(fs::DirectoryEntry), reinterpret_cast<::FsDirectoryEntry *>(out_entries.GetPointer())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetEntryCount(ams::sf::Out<s64> out) {
|
Result GetEntryCount(ams::sf::Out<s64> out) {
|
||||||
return fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer());
|
R_RETURN(fsDirGetEntryCount(std::addressof(m_base_dir), out.GetPointer()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(fssrv::sf::IsIDirectory<RemoteDirectory>);
|
static_assert(fssrv::sf::IsIDirectory<RemoteDirectory>);
|
||||||
@@ -196,61 +199,61 @@ namespace ams::fssrv::impl {
|
|||||||
public:
|
public:
|
||||||
/* Command API. */
|
/* Command API. */
|
||||||
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option) {
|
Result CreateFile(const fssrv::sf::Path &path, s64 size, s32 option) {
|
||||||
return fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option);
|
R_RETURN(fsFsCreateFile(std::addressof(m_base_fs), path.str, size, option));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteFile(const fssrv::sf::Path &path) {
|
Result DeleteFile(const fssrv::sf::Path &path) {
|
||||||
return fsFsDeleteFile(std::addressof(m_base_fs), path.str);
|
R_RETURN(fsFsDeleteFile(std::addressof(m_base_fs), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateDirectory(const fssrv::sf::Path &path) {
|
Result CreateDirectory(const fssrv::sf::Path &path) {
|
||||||
return fsFsCreateDirectory(std::addressof(m_base_fs), path.str);
|
R_RETURN(fsFsCreateDirectory(std::addressof(m_base_fs), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectory(const fssrv::sf::Path &path) {
|
Result DeleteDirectory(const fssrv::sf::Path &path) {
|
||||||
return fsFsDeleteDirectory(std::addressof(m_base_fs), path.str);
|
R_RETURN(fsFsDeleteDirectory(std::addressof(m_base_fs), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path) {
|
Result DeleteDirectoryRecursively(const fssrv::sf::Path &path) {
|
||||||
return fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str);
|
R_RETURN(fsFsDeleteDirectoryRecursively(std::addressof(m_base_fs), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
|
Result RenameFile(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
|
||||||
return fsFsRenameFile(std::addressof(m_base_fs), old_path.str, new_path.str);
|
R_RETURN(fsFsRenameFile(std::addressof(m_base_fs), old_path.str, new_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RenameDirectory(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
|
Result RenameDirectory(const fssrv::sf::Path &old_path, const fssrv::sf::Path &new_path) {
|
||||||
return fsFsRenameDirectory(std::addressof(m_base_fs), old_path.str, new_path.str);
|
R_RETURN(fsFsRenameDirectory(std::addressof(m_base_fs), old_path.str, new_path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetEntryType(ams::sf::Out<u32> out, const fssrv::sf::Path &path) {
|
Result GetEntryType(ams::sf::Out<u32> out, const fssrv::sf::Path &path) {
|
||||||
static_assert(sizeof(::FsDirEntryType) == sizeof(u32));
|
static_assert(sizeof(::FsDirEntryType) == sizeof(u32));
|
||||||
return fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer()));
|
R_RETURN(fsFsGetEntryType(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsDirEntryType *>(out.GetPointer())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Commit() {
|
Result Commit() {
|
||||||
return fsFsCommit(std::addressof(m_base_fs));
|
R_RETURN(fsFsCommit(std::addressof(m_base_fs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
|
Result GetFreeSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
|
||||||
return fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
|
R_RETURN(fsFsGetFreeSpace(std::addressof(m_base_fs), path.str, out.GetPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
|
Result GetTotalSpaceSize(ams::sf::Out<s64> out, const fssrv::sf::Path &path) {
|
||||||
return fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer());
|
R_RETURN(fsFsGetTotalSpace(std::addressof(m_base_fs), path.str, out.GetPointer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CleanDirectoryRecursively(const fssrv::sf::Path &path) {
|
Result CleanDirectoryRecursively(const fssrv::sf::Path &path) {
|
||||||
return fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), path.str);
|
R_RETURN(fsFsCleanDirectoryRecursively(std::addressof(m_base_fs), path.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path) {
|
Result GetFileTimeStampRaw(ams::sf::Out<fs::FileTimeStampRaw> out, const fssrv::sf::Path &path) {
|
||||||
static_assert(sizeof(fs::FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
static_assert(sizeof(fs::FileTimeStampRaw) == sizeof(::FsTimeStampRaw));
|
||||||
return fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer()));
|
R_RETURN(fsFsGetFileTimeStampRaw(std::addressof(m_base_fs), path.str, reinterpret_cast<::FsTimeStampRaw *>(out.GetPointer())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result QueryEntry(const ams::sf::OutBuffer &out_buf, const ams::sf::InBuffer &in_buf, s32 query_id, const fssrv::sf::Path &path) {
|
Result QueryEntry(const ams::sf::OutNonSecureBuffer &out_buf, const ams::sf::InNonSecureBuffer &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));
|
R_RETURN(fsFsQueryEntry(std::addressof(m_base_fs), out_buf.GetPointer(), out_buf.GetSize(), in_buf.GetPointer(), in_buf.GetSize(), path.str, static_cast<FsFileSystemQueryId>(query_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode);
|
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