Return FSError instead of FSStatus in FSWrapper

This commit is contained in:
Maschell 2022-08-07 19:22:20 +02:00
parent 030195238f
commit aa58f1745f
9 changed files with 377 additions and 312 deletions

View File

@ -16,7 +16,7 @@ DECL_FUNCTION(FSStatus, FSOpenDir, FSClient *client, FSCmdBlock *block, const ch
[c = client, b = block, h = handle, p = path](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, p = path](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSOpenDir(c, b, p, h, realErrorMask); return real_FSOpenDir(c, b, p, h, realErrorMask);
}, },
[f = getFullPathForClient(client, path), h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [f = getFullPathForClient(client, path), h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSOpenDirWrapper(f.c_str(), h); return layer->FSOpenDirWrapper(f.c_str(), h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -34,7 +34,7 @@ DECL_FUNCTION(FSStatus, FSOpenDirAsync, FSClient *client, FSCmdBlock *block, con
[c = client, b = block, h = handle, p = path, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, p = path, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSOpenDirAsync(c, b, p, h, realErrorMask, a); return real_FSOpenDirAsync(c, b, p, h, realErrorMask, a);
}, },
[f = getFullPathForClient(client, path), h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [f = getFullPathForClient(client, path), h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSOpenDirWrapper(f.c_str(), h); return layer->FSOpenDirWrapper(f.c_str(), h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -51,7 +51,7 @@ DECL_FUNCTION(FSStatus, FSReadDir, FSClient *client, FSCmdBlock *block, FSDirect
[c = client, b = block, h = handle, e = entry](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, e = entry](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSReadDir(c, b, h, e, realErrorMask); return real_FSReadDir(c, b, h, e, realErrorMask);
}, },
[h = handle, e = entry](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, e = entry](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSReadDirWrapper(h, e); return layer->FSReadDirWrapper(h, e);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -68,7 +68,7 @@ DECL_FUNCTION(FSStatus, FSReadDirAsync, FSClient *client, FSCmdBlock *block, FSD
[c = client, b = block, h = handle, e = entry, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, e = entry, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSReadDirAsync(c, b, h, e, realErrorMask, a); return real_FSReadDirAsync(c, b, h, e, realErrorMask, a);
}, },
[h = handle, e = entry](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, e = entry](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSReadDirWrapper(h, e); return layer->FSReadDirWrapper(h, e);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -85,7 +85,7 @@ DECL_FUNCTION(FSStatus, FSCloseDir, FSClient *client, FSCmdBlock *block, FSDirec
[c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSCloseDir(c, b, h, realErrorMask); return real_FSCloseDir(c, b, h, realErrorMask);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSCloseDirWrapper(h); return layer->FSCloseDirWrapper(h);
}, },
[h = handle, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus { [h = handle, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus {
@ -110,7 +110,7 @@ DECL_FUNCTION(FSStatus, FSCloseDirAsync, FSClient *client, FSCmdBlock *block, FS
[c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSCloseDirAsync(c, b, h, realErrorMask, a); return real_FSCloseDirAsync(c, b, h, realErrorMask, a);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSCloseDirWrapper(h); return layer->FSCloseDirWrapper(h);
}, },
[c = client, b = block, h = handle, a = asyncData, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus { [c = client, b = block, h = handle, a = asyncData, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus {
@ -135,7 +135,7 @@ DECL_FUNCTION(FSStatus, FSRewindDir, FSClient *client, FSCmdBlock *block, FSDire
[c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSRewindDir(c, b, h, realErrorMask); return real_FSRewindDir(c, b, h, realErrorMask);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSRewindDirWrapper(h); return layer->FSRewindDirWrapper(h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -152,7 +152,7 @@ DECL_FUNCTION(FSStatus, FSRewindDirAsync, FSClient *client, FSCmdBlock *block, F
[c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSRewindDirAsync(c, b, h, realErrorMask, a); return real_FSRewindDirAsync(c, b, h, realErrorMask, a);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSRewindDirWrapper(h); return layer->FSRewindDirWrapper(h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -169,7 +169,7 @@ DECL_FUNCTION(FSStatus, FSMakeDir, FSClient *client, FSCmdBlock *block, const ch
[c = client, b = block, p = path](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSMakeDir(c, b, p, realErrorMask); return real_FSMakeDir(c, b, p, realErrorMask);
}, },
[f = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [f = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSMakeDirWrapper(f.c_str()); return layer->FSMakeDirWrapper(f.c_str());
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -186,7 +186,7 @@ DECL_FUNCTION(FSStatus, FSMakeDirAsync, FSClient *client, FSCmdBlock *block, con
[c = client, b = block, p = path, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSMakeDirAsync(c, b, p, realErrorMask, a); return real_FSMakeDirAsync(c, b, p, realErrorMask, a);
}, },
[f = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [f = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSMakeDirWrapper(f.c_str()); return layer->FSMakeDirWrapper(f.c_str());
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);

View File

@ -15,7 +15,7 @@ DECL_FUNCTION(FSStatus, FSOpenFileEx, FSClient *client, FSCmdBlock *block, const
[c = client, b = block, p = path, m = mode, cm = createMode, of = openFlag, pa = preallocSize, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, m = mode, cm = createMode, of = openFlag, pa = preallocSize, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSOpenFileEx(c, b, p, m, cm, of, pa, h, realErrorMask); return real_FSOpenFileEx(c, b, p, m, cm, of, pa, h, realErrorMask);
}, },
[f = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [f = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSOpenFileWrapper(f.c_str(), m, h); return layer->FSOpenFileWrapper(f.c_str(), m, h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -32,7 +32,7 @@ DECL_FUNCTION(FSStatus, FSOpenFileExAsync, FSClient *client, FSCmdBlock *block,
[c = client, b = block, p = path, m = mode, cm = createMode, of = openFlag, pa = preallocSize, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, m = mode, cm = createMode, of = openFlag, pa = preallocSize, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSOpenFileExAsync(c, b, p, m, cm, of, pa, h, realErrorMask, a); return real_FSOpenFileExAsync(c, b, p, m, cm, of, pa, h, realErrorMask, a);
}, },
[p = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [p = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSOpenFileWrapper(p.c_str(), m, h); return layer->FSOpenFileWrapper(p.c_str(), m, h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -49,7 +49,7 @@ DECL_FUNCTION(FSStatus, FSOpenFile, FSClient *client, FSCmdBlock *block, char *p
[c = client, b = block, p = path, m = mode, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, m = mode, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSOpenFile(c, b, p, m, h, realErrorMask); return real_FSOpenFile(c, b, p, m, h, realErrorMask);
}, },
[f = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [f = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSOpenFileWrapper(f.c_str(), m, h); return layer->FSOpenFileWrapper(f.c_str(), m, h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -66,7 +66,7 @@ DECL_FUNCTION(FSStatus, FSOpenFileAsync, FSClient *client, FSCmdBlock *block, co
[c = client, b = block, p = path, m = mode, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, m = mode, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSOpenFileAsync(c, b, p, m, h, realErrorMask, a); return real_FSOpenFileAsync(c, b, p, m, h, realErrorMask, a);
}, },
[p = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [p = getFullPathForClient(client, path), m = mode, h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSOpenFileWrapper(p.c_str(), m, h); return layer->FSOpenFileWrapper(p.c_str(), m, h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -83,7 +83,7 @@ DECL_FUNCTION(FSStatus, FSCloseFile, FSClient *client, FSCmdBlock *block, FSFile
[c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSCloseFile(c, b, h, realErrorMask); return real_FSCloseFile(c, b, h, realErrorMask);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSCloseFileWrapper(h); return layer->FSCloseFileWrapper(h);
}, },
[h = handle, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus { [h = handle, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus {
@ -108,7 +108,7 @@ DECL_FUNCTION(FSStatus, FSCloseFileAsync, FSClient *client, FSCmdBlock *block, F
[c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSCloseFileAsync(c, b, h, realErrorMask, a); return real_FSCloseFileAsync(c, b, h, realErrorMask, a);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSCloseFileWrapper(h); return layer->FSCloseFileWrapper(h);
}, },
[c = client, b = block, h = handle, a = asyncData, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus { [c = client, b = block, h = handle, a = asyncData, filename = __FILENAME__, func = __FUNCTION__, line = __LINE__](std::unique_ptr<IFSWrapper> &layer, FSStatus res) -> FSStatus {
@ -133,7 +133,7 @@ DECL_FUNCTION(FSStatus, FSGetStat, FSClient *client, FSCmdBlock *block, const ch
[c = client, b = block, p = path, s = stats](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, s = stats](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSGetStat(c, b, p, s, realErrorMask); return real_FSGetStat(c, b, p, s, realErrorMask);
}, },
[p = getFullPathForClient(client, path), s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [p = getFullPathForClient(client, path), s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSGetStatWrapper(p.c_str(), s); return layer->FSGetStatWrapper(p.c_str(), s);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -150,7 +150,7 @@ DECL_FUNCTION(FSStatus, FSGetStatAsync, FSClient *client, FSCmdBlock *block, con
[c = client, b = block, p = path, s = stats, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, s = stats, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSGetStatAsync(c, b, p, s, realErrorMask, a); return real_FSGetStatAsync(c, b, p, s, realErrorMask, a);
}, },
[p = getFullPathForClient(client, path), s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [p = getFullPathForClient(client, path), s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSGetStatWrapper(p.c_str(), s); return layer->FSGetStatWrapper(p.c_str(), s);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -167,7 +167,7 @@ DECL_FUNCTION(FSStatus, FSGetStatFile, FSClient *client, FSCmdBlock *block, FSFi
[c = client, b = block, h = handle, s = stats](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, s = stats](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSGetStatFile(c, b, h, s, realErrorMask); return real_FSGetStatFile(c, b, h, s, realErrorMask);
}, },
[h = handle, s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSGetStatFileWrapper(h, s); return layer->FSGetStatFileWrapper(h, s);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -184,7 +184,7 @@ DECL_FUNCTION(FSStatus, FSGetStatFileAsync, FSClient *client, FSCmdBlock *block,
[c = client, b = block, h = handle, s = stats, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, s = stats, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSGetStatFileAsync(c, b, h, s, realErrorMask, a); return real_FSGetStatFileAsync(c, b, h, s, realErrorMask, a);
}, },
[h = handle, s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, s = stats](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSGetStatFileWrapper(h, s); return layer->FSGetStatFileWrapper(h, s);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -201,7 +201,7 @@ DECL_FUNCTION(FSStatus, FSReadFile, FSClient *client, FSCmdBlock *block, void *b
[c = client, b = block, h = handle, s = size, co = count, bu = buffer, u = unk1](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, s = size, co = count, bu = buffer, u = unk1](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSReadFile(c, b, bu, s, co, h, u, realErrorMask); return real_FSReadFile(c, b, bu, s, co, h, u, realErrorMask);
}, },
[b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSReadFileWrapper(b, s, c, h, u); return layer->FSReadFileWrapper(b, s, c, h, u);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -219,7 +219,7 @@ DECL_FUNCTION(FSStatus, FSReadFileAsync, FSClient *client, FSCmdBlock *block, vo
[c = client, b = block, h = handle, s = size, co = count, bu = buffer, u = unk1, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, s = size, co = count, bu = buffer, u = unk1, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSReadFileAsync(c, b, bu, s, co, h, u, realErrorMask, a); return real_FSReadFileAsync(c, b, bu, s, co, h, u, realErrorMask, a);
}, },
[b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSReadFileWrapper(b, s, c, h, u); return layer->FSReadFileWrapper(b, s, c, h, u);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -236,7 +236,7 @@ DECL_FUNCTION(FSStatus, FSReadFileWithPos, FSClient *client, FSCmdBlock *block,
[c = client, b = block, h = handle, s = size, co = count, p = pos, bu = buffer, u = unk1](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, s = size, co = count, p = pos, bu = buffer, u = unk1](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSReadFileWithPos(c, b, bu, s, co, p, h, u, realErrorMask); return real_FSReadFileWithPos(c, b, bu, s, co, p, h, u, realErrorMask);
}, },
[b = buffer, s = size, c = count, p = pos, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [b = buffer, s = size, c = count, p = pos, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSReadFileWithPosWrapper(b, s, c, p, h, u); return layer->FSReadFileWithPosWrapper(b, s, c, p, h, u);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -254,7 +254,7 @@ DECL_FUNCTION(FSStatus, FSReadFileWithPosAsync, FSClient *client, FSCmdBlock *bl
[c = client, b = block, h = handle, s = size, co = count, p = pos, bu = buffer, u = unk1, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, s = size, co = count, p = pos, bu = buffer, u = unk1, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSReadFileWithPosAsync(c, b, bu, s, co, p, h, u, realErrorMask, a); return real_FSReadFileWithPosAsync(c, b, bu, s, co, p, h, u, realErrorMask, a);
}, },
[b = buffer, s = size, c = count, p = pos, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [b = buffer, s = size, c = count, p = pos, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSReadFileWithPosWrapper(b, s, c, p, h, u); return layer->FSReadFileWithPosWrapper(b, s, c, p, h, u);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -271,7 +271,7 @@ DECL_FUNCTION(FSStatus, FSSetPosFile, FSClient *client, FSCmdBlock *block, FSFil
[c = client, b = block, h = handle, p = pos](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, p = pos](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSSetPosFile(c, b, h, p, realErrorMask); return real_FSSetPosFile(c, b, h, p, realErrorMask);
}, },
[h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSSetPosFileWrapper(h, p); return layer->FSSetPosFileWrapper(h, p);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -288,7 +288,7 @@ DECL_FUNCTION(FSStatus, FSSetPosFileAsync, FSClient *client, FSCmdBlock *block,
[c = client, b = block, h = handle, p = pos, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, p = pos, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSSetPosFileAsync(c, b, h, p, realErrorMask, a); return real_FSSetPosFileAsync(c, b, h, p, realErrorMask, a);
}, },
[h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSSetPosFileWrapper(h, p); return layer->FSSetPosFileWrapper(h, p);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -305,7 +305,7 @@ DECL_FUNCTION(FSStatus, FSGetPosFile, FSClient *client, FSCmdBlock *block, FSFil
[c = client, b = block, h = handle, p = pos](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, p = pos](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSGetPosFile(c, b, h, p, realErrorMask); return real_FSGetPosFile(c, b, h, p, realErrorMask);
}, },
[h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSGetPosFileWrapper(h, p); return layer->FSGetPosFileWrapper(h, p);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -322,7 +322,7 @@ DECL_FUNCTION(FSStatus, FSGetPosFileAsync, FSClient *client, FSCmdBlock *block,
[c = client, b = block, h = handle, p = pos, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, p = pos, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSGetPosFileAsync(c, b, h, p, realErrorMask, a); return real_FSGetPosFileAsync(c, b, h, p, realErrorMask, a);
}, },
[h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle, p = pos](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSGetPosFileWrapper(h, p); return layer->FSGetPosFileWrapper(h, p);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -339,7 +339,7 @@ DECL_FUNCTION(FSStatus, FSIsEof, FSClient *client, FSCmdBlock *block, FSFileHand
[c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSIsEof(c, b, h, realErrorMask); return real_FSIsEof(c, b, h, realErrorMask);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSIsEofWrapper(h); return layer->FSIsEofWrapper(h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -356,7 +356,7 @@ DECL_FUNCTION(FSStatus, FSIsEofAsync, FSClient *client, FSCmdBlock *block, FSFil
[c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSIsEofAsync(c, b, h, realErrorMask, a); return real_FSIsEofAsync(c, b, h, realErrorMask, a);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSIsEofWrapper(h); return layer->FSIsEofWrapper(h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -373,7 +373,7 @@ DECL_FUNCTION(FSStatus, FSWriteFile, FSClient *client, FSCmdBlock *block, uint8_
[c = client, b = block, bu = buffer, s = size, co = count, h = handle, u = unk1](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, bu = buffer, s = size, co = count, h = handle, u = unk1](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSWriteFile(c, b, bu, s, co, h, u, realErrorMask); return real_FSWriteFile(c, b, bu, s, co, h, u, realErrorMask);
}, },
[b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSWriteFileWrapper(b, s, c, h, u); return layer->FSWriteFileWrapper(b, s, c, h, u);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -391,7 +391,7 @@ DECL_FUNCTION(FSStatus, FSWriteFileAsync, FSClient *client, FSCmdBlock *block, u
[c = client, b = block, bu = buffer, s = size, co = count, h = handle, u = unk1, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, bu = buffer, s = size, co = count, h = handle, u = unk1, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSWriteFileAsync(c, b, bu, s, co, h, u, realErrorMask, a); return real_FSWriteFileAsync(c, b, bu, s, co, h, u, realErrorMask, a);
}, },
[b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [b = buffer, s = size, c = count, h = handle, u = unk1](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSWriteFileWrapper(b, s, c, h, u); return layer->FSWriteFileWrapper(b, s, c, h, u);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -408,7 +408,7 @@ DECL_FUNCTION(FSStatus, FSTruncateFile, FSClient *client, FSCmdBlock *block, FSF
[c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSTruncateFile(c, b, h, realErrorMask); return real_FSTruncateFile(c, b, h, realErrorMask);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSTruncateFileWrapper(h); return layer->FSTruncateFileWrapper(h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -425,7 +425,7 @@ DECL_FUNCTION(FSStatus, FSTruncateFileAsync, FSClient *client, FSCmdBlock *block
[c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSTruncateFileAsync(c, b, h, realErrorMask, a); return real_FSTruncateFileAsync(c, b, h, realErrorMask, a);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSTruncateFileWrapper(h); return layer->FSTruncateFileWrapper(h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -442,7 +442,7 @@ DECL_FUNCTION(FSStatus, FSRemove, FSClient *client, FSCmdBlock *block, const cha
[c = client, b = block, p = path](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSRemove(c, b, p, realErrorMask); return real_FSRemove(c, b, p, realErrorMask);
}, },
[p = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [p = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSRemoveWrapper(p.c_str()); return layer->FSRemoveWrapper(p.c_str());
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -459,7 +459,7 @@ DECL_FUNCTION(FSStatus, FSRemoveAsync, FSClient *client, FSCmdBlock *block, cons
[c = client, b = block, p = path, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, p = path, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSRemoveAsync(c, b, p, realErrorMask, a); return real_FSRemoveAsync(c, b, p, realErrorMask, a);
}, },
[p = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [p = getFullPathForClient(client, path)](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSRemoveWrapper(p.c_str()); return layer->FSRemoveWrapper(p.c_str());
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -476,7 +476,7 @@ DECL_FUNCTION(FSStatus, FSRename, FSClient *client, FSCmdBlock *block, const cha
[c = client, b = block, oP = oldPath, nP = newPath](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, oP = oldPath, nP = newPath](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSRename(c, b, oP, nP, realErrorMask); return real_FSRename(c, b, oP, nP, realErrorMask);
}, },
[oP = getFullPathForClient(client, oldPath), nP = getFullPathForClient(client, newPath)](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [oP = getFullPathForClient(client, oldPath), nP = getFullPathForClient(client, newPath)](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSRenameWrapper(oP.c_str(), nP.c_str()); return layer->FSRenameWrapper(oP.c_str(), nP.c_str());
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -499,7 +499,7 @@ DECL_FUNCTION(FSStatus, FSRenameAsync,
[c = client, b = block, oP = oldPath, nP = newPath, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, oP = oldPath, nP = newPath, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSRenameAsync(c, b, oP, nP, realErrorMask, a); return real_FSRenameAsync(c, b, oP, nP, realErrorMask, a);
}, },
[oP = getFullPathForClient(client, oldPath), nP = getFullPathForClient(client, newPath)](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [oP = getFullPathForClient(client, oldPath), nP = getFullPathForClient(client, newPath)](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSRenameWrapper(oP.c_str(), nP.c_str()); return layer->FSRenameWrapper(oP.c_str(), nP.c_str());
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);
@ -516,7 +516,7 @@ DECL_FUNCTION(FSStatus, FSFlushFile, FSClient *client, FSCmdBlock *block, [[mayb
[c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSFlushFile(c, b, h, realErrorMask); return real_FSFlushFile(c, b, h, realErrorMask);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSFlushFileWrapper(h); return layer->FSFlushFileWrapper(h);
}, },
SYNC_RESULT_HANDLER); SYNC_RESULT_HANDLER);
@ -533,7 +533,7 @@ DECL_FUNCTION(FSStatus, FSFlushFileAsync, FSClient *client, FSCmdBlock *block, [
[c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus { [c = client, b = block, h = handle, a = asyncData](FSErrorFlag realErrorMask) -> FSStatus {
return real_FSFlushFileAsync(c, b, h, realErrorMask, a); return real_FSFlushFileAsync(c, b, h, realErrorMask, a);
}, },
[h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSStatus { [h = handle](std::unique_ptr<IFSWrapper> &layer) -> FSError {
return layer->FSFlushFileWrapper(h); return layer->FSFlushFileWrapper(h);
}, },
ASYNC_RESULT_HANDLER); ASYNC_RESULT_HANDLER);

View File

@ -6,23 +6,27 @@
#include <algorithm> #include <algorithm>
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <coreinit/filesystem_fsa.h>
#include <cstdio> #include <cstdio>
#include <filesystem> #include <filesystem>
#include <sys/dirent.h> #include <sys/dirent.h>
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <sys/unistd.h> #include <sys/unistd.h>
FSStatus FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle) { FSError FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle) {
if (path == nullptr) {
return FS_ERROR_INVALID_PARAM;
}
if (!IsPathToReplace(path)) { if (!IsPathToReplace(path)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (handle == nullptr) { if (handle == nullptr) {
DEBUG_FUNCTION_LINE_ERR("[%s] handle was nullptr", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] handle was nullptr", getName().c_str());
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_PARAM;
} }
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
auto dirHandle = getNewDirHandle(); auto dirHandle = getNewDirHandle();
if (dirHandle) { if (dirHandle) {
@ -30,7 +34,6 @@ FSStatus FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle
auto newPath = GetNewPath(path); auto newPath = GetNewPath(path);
if ((dir = opendir(newPath.c_str()))) { if ((dir = opendir(newPath.c_str()))) {
dirHandle->dir = dir; dirHandle->dir = dir;
dirHandle->handle = (((uint32_t) dirHandle.get()) & 0x0FFFFFFF) | 0x30000000; dirHandle->handle = (((uint32_t) dirHandle.get()) & 0x0FFFFFFF) | 0x30000000;
*handle = dirHandle->handle; *handle = dirHandle->handle;
@ -43,26 +46,40 @@ FSStatus FSWrapper::FSOpenDirWrapper(const char *path, FSDirectoryHandle *handle
OSMemoryBarrier(); OSMemoryBarrier();
} }
} else { } else {
result = FS_STATUS_NOT_FOUND; auto err = errno;
if (err == ENOENT) {
DEBUG_FUNCTION_LINE("[%s] Open dir %s (%s) failed. FS_ERROR_NOT_FOUND", getName().c_str(), path, newPath.c_str());
return FS_ERROR_NOT_FOUND;
}
DEBUG_FUNCTION_LINE_ERR("[%s] Open dir %s (%s) failed. errno %d", getName().c_str(), path, newPath.c_str(), err);
if (err == EACCES) {
return FS_ERROR_PERMISSION_ERROR;
} else if (err == ENOTDIR) {
return FS_ERROR_NOT_DIR;
} else if (err == ENFILE || err == EMFILE) {
return FS_ERROR_MAX_DIRS;
}
return FS_ERROR_MEDIA_ERROR;
} }
} else { } else {
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to alloc dir handle", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to alloc dir handle", getName().c_str());
result = FS_STATUS_MAX; result = FS_ERROR_MAX_DIRS;
} }
return result; return result;
} }
FSStatus FSWrapper::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry *entry) { FSError FSWrapper::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry *entry) {
if (!isValidDirHandle(handle)) { if (!isValidDirHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto dirHandle = getDirFromHandle(handle); auto dirHandle = getDirFromHandle(handle);
DIR *dir = dirHandle->dir; DIR *dir = dirHandle->dir;
FSStatus result = FS_STATUS_END; FSError result = FS_ERROR_END_OF_DIR;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] readdir %08X (handle %08X)", getName().c_str(), dir, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] readdir %08X (handle %08X)", getName().c_str(), dir, handle);
do { do {
errno = 0;
struct dirent *entry_ = readdir(dir); struct dirent *entry_ = readdir(dir);
if (entry_) { if (entry_) {
@ -93,103 +110,109 @@ FSStatus FSWrapper::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry
} }
} }
} }
result = FS_STATUS_OK; result = FS_ERROR_OK;
} else {
auto err = errno;
if (err != 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to read dir %08X (handle %08X)", getName().c_str(), dir, handle);
result = FS_ERROR_MEDIA_ERROR;
}
} }
break; break;
} while (true); } while (true);
return result; return result;
} }
FSStatus FSWrapper::FSCloseDirWrapper(FSDirectoryHandle handle) { FSError FSWrapper::FSCloseDirWrapper(FSDirectoryHandle handle) {
if (!isValidDirHandle(handle)) { if (!isValidDirHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto dirHandle = getDirFromHandle(handle); auto dirHandle = getDirFromHandle(handle);
DIR *dir = dirHandle->dir; DIR *dir = dirHandle->dir;
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] closedir %08X (handle %08X)", getName().c_str(), dir, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] closedir %08X (handle %08X)", getName().c_str(), dir, handle);
if (closedir(dir) != 0) { if (closedir(dir) < 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close dir %08X (handle %08X)", getName().c_str(), dir, handle); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close dir %08X (handle %08X)", getName().c_str(), dir, handle);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} }
dirHandle->dir = nullptr; dirHandle->dir = nullptr;
return result; return result;
} }
FSStatus FSWrapper::FSRewindDirWrapper(FSDirectoryHandle handle) { FSError FSWrapper::FSRewindDirWrapper(FSDirectoryHandle handle) {
if (!isValidDirHandle(handle)) { if (!isValidDirHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto dirHandle = getDirFromHandle(handle); auto dirHandle = getDirFromHandle(handle);
DIR *dir = dirHandle->dir; DIR *dir = dirHandle->dir;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] rewindir %08X (handle %08X)", getName().c_str(), dir, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] rewinddir %08X (handle %08X)", getName().c_str(), dir, handle);
rewinddir(dir); rewinddir(dir);
return FS_STATUS_OK; return FS_ERROR_OK;
} }
FSStatus FSWrapper::FSMakeDirWrapper(const char *path) { FSError FSWrapper::FSMakeDirWrapper(const char *path) {
if (!IsPathToReplace(path)) { if (!IsPathToReplace(path)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (!pIsWriteable) { if (!pIsWriteable) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to create dir %s but layer is not writeable", getName().c_str(), path); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to create dir %s but layer is not writeable", getName().c_str(), path);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_PERMISSION_ERROR;
} }
DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED MAKE DIR"); DEBUG_FUNCTION_LINE_ERR("NOT IMPLEMENTED MAKE DIR");
return FS_STATUS_FATAL_ERROR; return FS_ERROR_UNSUPPORTED_COMMAND;
} }
FSStatus FSWrapper::FSOpenFileWrapper(const char *path, const char *mode, FSFileHandle *handle) { FSError FSWrapper::FSOpenFileWrapper(const char *path, const char *mode, FSFileHandle *handle) {
if (!IsPathToReplace(path)) { if (!IsPathToReplace(path)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (path == nullptr) { if (path == nullptr) {
DEBUG_FUNCTION_LINE_ERR("[%s] path was nullptr", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] path was nullptr", getName().c_str());
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_PARAM;
} }
if (mode == nullptr || handle == nullptr) { if (mode == nullptr || handle == nullptr) {
DEBUG_FUNCTION_LINE_ERR("[%s] mode or handle was nullptr", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] mode or handle was nullptr", getName().c_str());
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_PARAM;
} }
auto newPath = GetNewPath(path); auto newPath = GetNewPath(path);
if (pCheckIfDeleted && CheckFileShouldBeIgnored(newPath)) { if (pCheckIfDeleted && CheckFileShouldBeIgnored(newPath)) {
return static_cast<FSStatus>((FS_STATUS_NOT_FOUND & 0x0000FFFF) | FS_STATUS_FORCE_NO_FALLBACK); return static_cast<FSError>((FS_ERROR_NOT_FOUND & FS_ERROR_REAL_MASK) | FS_ERROR_FORCE_NO_FALLBACK);
} }
auto result = FS_STATUS_OK; auto result = FS_ERROR_OK;
int _mode; int _mode;
// Map flags to open modes // Map flags to open modes
if (!IsFileModeAllowed(mode)) { if (!IsFileModeAllowed(mode)) {
OSReport("## WARN ## [%s] Given mode is not allowed %s", getName().c_str(), mode); OSReport("## WARN ## [%s] Given mode is not allowed %s", getName().c_str(), mode);
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Given mode is not allowed %s", getName().c_str(), mode); DEBUG_FUNCTION_LINE("[%s] Given mode is not allowed %s", getName().c_str(), mode);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} }
if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0) { if (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0) {
_mode = 0x000; _mode = O_RDONLY;
} else if (strcmp(mode, "r+") == 0) { } else if (strcmp(mode, "r+") == 0) {
_mode = 0x002; _mode = O_RDWR;
} else if (strcmp(mode, "w") == 0) { } else if (strcmp(mode, "w") == 0) {
_mode = 0x601; _mode = O_WRONLY | O_CREAT | O_TRUNC;
} else if (strcmp(mode, "w+") == 0) { } else if (strcmp(mode, "w+") == 0) {
_mode = 0x602; _mode = O_RDWR | O_CREAT | O_TRUNC;
} else if (strcmp(mode, "a") == 0) { } else if (strcmp(mode, "a") == 0) {
_mode = 0x209; _mode = O_WRONLY | O_CREAT | O_APPEND;
} else if (strcmp(mode, "a+") == 0) { } else if (strcmp(mode, "a+") == 0) {
_mode = 0x20A; _mode = O_RDWR | O_CREAT | O_APPEND;
} else { } else {
DEBUG_FUNCTION_LINE_ERR("[%s] mode \"%s\" was allowed but is unsupported", getName().c_str(), mode); DEBUG_FUNCTION_LINE_ERR("[%s] mode \"%s\" was allowed but is unsupported", getName().c_str(), mode);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} }
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Open %s (as %s) mode %s,", getName().c_str(), path, newPath.c_str(), mode); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Open %s (as %s) mode %s,", getName().c_str(), path, newPath.c_str(), mode);
@ -210,30 +233,49 @@ FSStatus FSWrapper::FSOpenFileWrapper(const char *path, const char *mode, FSFile
} else { } else {
close(fd); close(fd);
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to alloc new fileHandle", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to alloc new fileHandle", getName().c_str());
result = FS_STATUS_MAX; result = FS_ERROR_MAX_FILES;
} }
} else { } else {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] File not found %s (%s)", getName().c_str(), path, newPath.c_str()); auto err = errno;
result = FS_STATUS_NOT_FOUND; if (err == ENOENT) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] File not found %s (%s)", getName().c_str(), path, newPath.c_str());
result = FS_ERROR_NOT_FOUND;
} else {
DEBUG_FUNCTION_LINE("[%s] Open file %s (%s) failed. errno %d ", getName().c_str(), path, newPath.c_str(), err);
if (err == EACCES) {
return FS_ERROR_PERMISSION_ERROR;
} else if (err == ENOENT) {
result = FS_ERROR_NOT_FOUND;
} else if (err == EEXIST) {
result = FS_ERROR_ALREADY_EXISTS;
} else if (err == EISDIR) {
result = FS_ERROR_NOT_FILE;
} else if (err == ENOTDIR) {
result = FS_ERROR_NOT_DIR;
} else if (err == ENFILE || err == EMFILE) {
result = FS_ERROR_MAX_FILES;
}
err = FS_ERROR_MEDIA_ERROR;
}
} }
return result; return result;
} }
FSStatus FSWrapper::FSCloseFileWrapper(FSFileHandle handle) { FSError FSWrapper::FSCloseFileWrapper(FSFileHandle handle) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Close %d (handle %08X)", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Close %d (handle %08X)", getName().c_str(), real_fd, handle);
if (close(real_fd) != 0) { if (close(real_fd) != 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close %d (handle %08X) ", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close %d (handle %08X) ", getName().c_str(), real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} }
fileHandle->fd = -1; fileHandle->fd = -1;
return result; return result;
@ -256,30 +298,29 @@ bool FSWrapper::CheckFileShouldBeIgnored(std::string &path) {
return false; return false;
} }
FSStatus FSWrapper::FSGetStatWrapper(const char *path, FSStat *stats) { FSError FSWrapper::FSGetStatWrapper(const char *path, FSStat *stats) {
if (path == nullptr || stats == nullptr) { if (path == nullptr || stats == nullptr) {
DEBUG_FUNCTION_LINE_ERR("[%s] path was or stats nullptr", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] path was or stats nullptr", getName().c_str());
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_PARAM;
} }
if (!IsPathToReplace(path)) { if (!IsPathToReplace(path)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto newPath = GetNewPath(path); auto newPath = GetNewPath(path);
struct stat path_stat {}; struct stat path_stat {};
if (pCheckIfDeleted && CheckFileShouldBeIgnored(newPath)) { if (pCheckIfDeleted && CheckFileShouldBeIgnored(newPath)) {
return static_cast<FSStatus>((FS_STATUS_NOT_FOUND & 0x0000FFFF) | FS_STATUS_FORCE_NO_FALLBACK); return static_cast<FSError>((FS_ERROR_NOT_FOUND & FS_ERROR_REAL_MASK) | FS_ERROR_FORCE_NO_FALLBACK);
} }
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] stat of %s (%s)", getName().c_str(), path, newPath.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("[%s] stat of %s (%s)", getName().c_str(), path, newPath.c_str());
if (stat(newPath.c_str(), &path_stat) < 0) { if (stat(newPath.c_str(), &path_stat) < 0) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Path %s (%s) not found ", getName().c_str(), path, newPath.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Path %s (%s) not found ", getName().c_str(), path, newPath.c_str());
result = FS_STATUS_NOT_FOUND; result = FS_ERROR_NOT_FOUND;
} else { } else {
memset(&(stats->flags), 0, sizeof(stats->flags)); memset(&(stats->flags), 0, sizeof(stats->flags));
if (S_ISDIR(path_stat.st_mode)) { if (S_ISDIR(path_stat.st_mode)) {
@ -296,9 +337,9 @@ FSStatus FSWrapper::FSGetStatWrapper(const char *path, FSStat *stats) {
return result; return result;
} }
FSStatus FSWrapper::FSGetStatFileWrapper(FSFileHandle handle, FSStat *stats) { FSError FSWrapper::FSGetStatFileWrapper(FSFileHandle handle, FSStat *stats) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
@ -306,11 +347,11 @@ FSStatus FSWrapper::FSGetStatFileWrapper(FSFileHandle handle, FSStat *stats) {
struct stat path_stat {}; struct stat path_stat {};
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] fstat of fd %d (FSFileHandle %08X)", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] fstat of fd %d (FSFileHandle %08X)", getName().c_str(), real_fd, handle);
if (fstat(real_fd, &path_stat) < 0) { if (fstat(real_fd, &path_stat) < 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] fstat of fd %d (FSFileHandle %08X) failed", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] fstat of fd %d (FSFileHandle %08X) failed", getName().c_str(), real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} else { } else {
memset(&(stats->flags), 0, sizeof(stats->flags)); memset(&(stats->flags), 0, sizeof(stats->flags));
@ -324,44 +365,48 @@ FSStatus FSWrapper::FSGetStatFileWrapper(FSFileHandle handle, FSStat *stats) {
return result; return result;
} }
FSStatus FSWrapper::FSReadFileWrapper(void *buffer, uint32_t size, uint32_t count, FSFileHandle handle, [[maybe_unused]] uint32_t unk1) { FSError FSWrapper::FSReadFileWrapper(void *buffer, uint32_t size, uint32_t count, FSFileHandle handle, [[maybe_unused]] uint32_t unk1) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (size * count == 0) { if (size * count == 0) {
return FS_STATUS_OK; return FS_ERROR_OK;
} }
if (buffer == nullptr) { if (buffer == nullptr) {
DEBUG_FUNCTION_LINE_ERR("[%s] buffer is null but size * count is not 0 (It's: %d)", getName().c_str(), size * count); DEBUG_FUNCTION_LINE_ERR("[%s] buffer is null but size * count is not 0 (It's: %d)", getName().c_str(), size * count);
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_BUFFER;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Read %u bytes of fd %08X (FSFileHandle %08X) to buffer %08X", getName().c_str(), size * count, real_fd, handle, buffer); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Read %u bytes of fd %08X (FSFileHandle %08X) to buffer %08X", getName().c_str(), size * count, real_fd, handle, buffer);
int32_t read = readIntoBuffer(real_fd, buffer, size, count); int64_t read = readIntoBuffer(real_fd, buffer, size, count);
FSStatus result; FSError result;
if (read < 0) { if (read < 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] read %u bytes of fd %d (FSFileHandle %08X) failed", getName().c_str(), size * count, real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] read %u bytes of fd %d (FSFileHandle %08X) failed", getName().c_str(), size * count, real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; auto err = errno;
if (err == EBADF || err == EROFS) {
return FS_ERROR_ACCESS_ERROR;
}
result = FS_ERROR_MEDIA_ERROR;
} else { } else {
result = static_cast<FSStatus>((uint32_t) (read & 0xFFFFFFFF) / size); result = static_cast<FSError>(((uint32_t) read) / size);
} }
return result; return result;
} }
FSStatus FSWrapper::FSReadFileWithPosWrapper(void *buffer, uint32_t size, uint32_t count, uint32_t pos, FSFileHandle handle, int32_t unk1) { FSError FSWrapper::FSReadFileWithPosWrapper(void *buffer, uint32_t size, uint32_t count, uint32_t pos, FSFileHandle handle, int32_t unk1) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Read from with position.", getName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Read from with position.", getName().c_str());
FSStatus result; FSError result;
if ((result = this->FSSetPosFileWrapper(handle, pos)) != FS_STATUS_OK) { if ((result = this->FSSetPosFileWrapper(handle, pos)) != FS_ERROR_OK) {
return result; return result;
} }
@ -370,20 +415,24 @@ FSStatus FSWrapper::FSReadFileWithPosWrapper(void *buffer, uint32_t size, uint32
return result; return result;
} }
FSStatus FSWrapper::FSSetPosFileWrapper(FSFileHandle handle, uint32_t pos) { FSError FSWrapper::FSSetPosFileWrapper(FSFileHandle handle, uint32_t pos) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %d (FSFileHandle %08X) to get current position for truncation", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %d (FSFileHandle %08X) to get current position for truncation", getName().c_str(), real_fd, handle);
if (lseek(real_fd, (off_t) pos, SEEK_SET) != pos) { off_t newPos;
if ((newPos = lseek(real_fd, (off_t) pos, SEEK_SET)) != pos) {
DEBUG_FUNCTION_LINE_ERR("[%s] lseek fd %d (FSFileHandle %08X) to position %u failed", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] lseek fd %d (FSFileHandle %08X) to position %u failed", getName().c_str(), real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; if (newPos < 0) {
// TODO: read errno
}
result = FS_ERROR_MEDIA_ERROR;
} else { } else {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] pos set to %u for fd %d (FSFileHandle %08X)", getName().c_str(), pos, real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] pos set to %u for fd %d (FSFileHandle %08X)", getName().c_str(), pos, real_fd, handle);
} }
@ -391,13 +440,13 @@ FSStatus FSWrapper::FSSetPosFileWrapper(FSFileHandle handle, uint32_t pos) {
return result; return result;
} }
FSStatus FSWrapper::FSGetPosFileWrapper(FSFileHandle handle, uint32_t *pos) { FSError FSWrapper::FSGetPosFileWrapper(FSFileHandle handle, uint32_t *pos) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
@ -405,86 +454,88 @@ FSStatus FSWrapper::FSGetPosFileWrapper(FSFileHandle handle, uint32_t *pos) {
off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR); off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR);
if (currentPos == -1) { if (currentPos == -1) {
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) of fd (handle %08X) to check EoF", getName().c_str(), currentPos, real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) of fd (handle %08X) to check EoF", getName().c_str(), currentPos, real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} else { } else {
*pos = currentPos; *pos = currentPos;
} }
return result; return result;
} }
FSStatus FSWrapper::FSIsEofWrapper(FSFileHandle handle) { FSError FSWrapper::FSIsEofWrapper(FSFileHandle handle) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
FSStatus result; FSError result;
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get current position for truncation", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get current position for EOF detection", getName().c_str(), real_fd, handle);
off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR); off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR);
DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get end position for truncation", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get end position for EOF detection", getName().c_str(), real_fd, handle);
off_t endPos = lseek(real_fd, (off_t) 0, SEEK_END); off_t endPos = lseek(real_fd, (off_t) 0, SEEK_END);
if (currentPos == -1 || endPos == -1) { if (currentPos == -1 || endPos == -1) {
// TODO: check errno
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) or endPos (res: %lld) of fd (handle %08X) to check EoF", getName().c_str(), currentPos, endPos, real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position (res: %lld) or endPos (res: %lld) of fd (handle %08X) to check EoF", getName().c_str(), currentPos, endPos, real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} else if (currentPos == endPos) { } else if (currentPos == endPos) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] FSIsEof END for %d\n", getName().c_str(), real_fd); DEBUG_FUNCTION_LINE_VERBOSE("[%s] FSIsEof END for %d\n", getName().c_str(), real_fd);
result = FS_STATUS_END; result = FS_ERROR_END_OF_FILE;
} else { } else {
lseek(real_fd, currentPos, SEEK_CUR); lseek(real_fd, currentPos, SEEK_CUR);
DEBUG_FUNCTION_LINE_VERBOSE("[%s] FSIsEof OK for %d\n", getName().c_str(), real_fd); DEBUG_FUNCTION_LINE_VERBOSE("[%s] FSIsEof OK for %d\n", getName().c_str(), real_fd);
result = FS_STATUS_OK; result = FS_ERROR_OK;
} }
return result; return result;
} }
FSStatus FSWrapper::FSTruncateFileWrapper(FSFileHandle handle) { FSError FSWrapper::FSTruncateFileWrapper(FSFileHandle handle) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (!pIsWriteable) { if (!pIsWriteable) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to truncate fd %d (handle %08X) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to truncate fd %d (handle %08X) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get current position for truncation", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] lseek fd %08X (FSFileHandle %08X) to get current position for truncation", getName().c_str(), real_fd, handle);
off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR); off_t currentPos = lseek(real_fd, (off_t) 0, SEEK_CUR);
if (currentPos == -1) { if (currentPos == -1) {
// TODO check errno
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position of fd (handle %08X) to truncate file", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to get current position of fd (handle %08X) to truncate file", getName().c_str(), real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} else { } else {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Truncate fd %08X (FSFileHandle %08X) to %lld bytes ", getName().c_str(), real_fd, handle, currentPos); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Truncate fd %08X (FSFileHandle %08X) to %lld bytes ", getName().c_str(), real_fd, handle, currentPos);
if (ftruncate(real_fd, currentPos) < 0) { if (ftruncate(real_fd, currentPos) < 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] ftruncate failed for fd %08X (FSFileHandle %08X) errno %d", getName().c_str(), real_fd, handle, errno); DEBUG_FUNCTION_LINE_ERR("[%s] ftruncate failed for fd %08X (FSFileHandle %08X) errno %d", getName().c_str(), real_fd, handle, errno);
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} }
} }
return result; return result;
} }
FSStatus FSWrapper::FSWriteFileWrapper(uint8_t *buffer, uint32_t size, uint32_t count, FSFileHandle handle, [[maybe_unused]] uint32_t unk1) { FSError FSWrapper::FSWriteFileWrapper(uint8_t *buffer, uint32_t size, uint32_t count, FSFileHandle handle, [[maybe_unused]] uint32_t unk1) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (!pIsWriteable) { if (!pIsWriteable) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to write to fd %d (handle %08X) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to write to fd %d (handle %08X) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
FSStatus result; FSError result;
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
@ -494,26 +545,26 @@ FSStatus FSWrapper::FSWriteFileWrapper(uint8_t *buffer, uint32_t size, uint32_t
auto err = errno; auto err = errno;
DEBUG_FUNCTION_LINE_ERR("[%s] Write failed %u bytes to fd %08X (FSFileHandle %08X) from buffer %08X errno %d", getName().c_str(), count * size, real_fd, handle, buffer, err); DEBUG_FUNCTION_LINE_ERR("[%s] Write failed %u bytes to fd %08X (FSFileHandle %08X) from buffer %08X errno %d", getName().c_str(), count * size, real_fd, handle, buffer, err);
if (err == EFBIG) { if (err == EFBIG) {
result = FS_STATUS_FILE_TOO_BIG; result = FS_ERROR_FILE_TOO_BIG;
} else if (err == EACCES) { } else if (err == EACCES) {
result = FS_STATUS_ACCESS_ERROR; result = FS_ERROR_ACCESS_ERROR;
} else { } else {
result = FS_STATUS_MEDIA_ERROR; result = FS_ERROR_MEDIA_ERROR;
} }
} else { } else {
result = static_cast<FSStatus>((uint32_t) (writeRes & 0xFFFFFFFF) / size); result = static_cast<FSError>(((uint32_t) writeRes) / size);
} }
return result; return result;
} }
FSStatus FSWrapper::FSRemoveWrapper(const char *path) { FSError FSWrapper::FSRemoveWrapper(const char *path) {
if (!IsPathToReplace(path)) { if (!IsPathToReplace(path)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (!pIsWriteable) { if (!pIsWriteable) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to remove %s but layer is not writeable", getName().c_str(), path); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to remove %s but layer is not writeable", getName().c_str(), path);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_PERMISSION_ERROR;
} }
auto newPath = GetNewPath(path); auto newPath = GetNewPath(path);
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Remove %s (%s)", getName().c_str(), path, newPath.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Remove %s (%s)", getName().c_str(), path, newPath.c_str());
@ -521,26 +572,26 @@ FSStatus FSWrapper::FSRemoveWrapper(const char *path) {
auto err = errno; auto err = errno;
DEBUG_FUNCTION_LINE_ERR("[%s] rename failed %s (%s) errno %d", getName().c_str(), path, newPath.c_str(), err); DEBUG_FUNCTION_LINE_ERR("[%s] rename failed %s (%s) errno %d", getName().c_str(), path, newPath.c_str(), err);
if (err == ENOTDIR) { if (err == ENOTDIR) {
return FS_STATUS_NOT_DIR; return FS_ERROR_NOT_DIR;
} else if (err == EACCES) { } else if (err == EACCES) {
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} else if (err == EISDIR) { } else if (err == EISDIR) {
return FS_STATUS_NOT_FILE; return FS_ERROR_NOT_FILE;
} else if (err == EPERM) { } else if (err == EPERM) {
return FS_STATUS_PERMISSION_ERROR; return FS_ERROR_PERMISSION_ERROR;
} }
return FS_STATUS_MEDIA_ERROR; return FS_ERROR_MEDIA_ERROR;
} }
return FS_STATUS_OK; return FS_ERROR_OK;
} }
FSStatus FSWrapper::FSRenameWrapper(const char *oldPath, const char *newPath) { FSError FSWrapper::FSRenameWrapper(const char *oldPath, const char *newPath) {
if (!IsPathToReplace(oldPath) || !IsPathToReplace(newPath)) { if (!IsPathToReplace(oldPath) || !IsPathToReplace(newPath)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (!pIsWriteable) { if (!pIsWriteable) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to rename %s to %s but layer is not writeable", getName().c_str(), oldPath, newPath); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to rename %s to %s but layer is not writeable", getName().c_str(), oldPath, newPath);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_PERMISSION_ERROR;
} }
auto oldPathRedirect = GetNewPath(oldPath); auto oldPathRedirect = GetNewPath(oldPath);
auto newPathRedirect = GetNewPath(newPath); auto newPathRedirect = GetNewPath(newPath);
@ -549,36 +600,41 @@ FSStatus FSWrapper::FSRenameWrapper(const char *oldPath, const char *newPath) {
auto err = errno; auto err = errno;
DEBUG_FUNCTION_LINE_ERR("[%s] Rename failed %s (%s) -> %s (%s). errno %d", getName().c_str(), oldPath, oldPathRedirect.c_str(), newPath, newPathRedirect.c_str(), err); DEBUG_FUNCTION_LINE_ERR("[%s] Rename failed %s (%s) -> %s (%s). errno %d", getName().c_str(), oldPath, oldPathRedirect.c_str(), newPath, newPathRedirect.c_str(), err);
if (err == ENOTDIR) { if (err == ENOTDIR) {
return FS_STATUS_NOT_DIR; return FS_ERROR_NOT_DIR;
} else if (err == EACCES) { } else if (err == EACCES) {
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} else if (err == EISDIR) { } else if (err == EISDIR) {
return FS_STATUS_NOT_FILE; return FS_ERROR_NOT_FILE;
} else if (err == EPERM) { } else if (err == EPERM) {
return FS_STATUS_PERMISSION_ERROR; return FS_ERROR_PERMISSION_ERROR;
} }
return FS_STATUS_MEDIA_ERROR; return FS_ERROR_MEDIA_ERROR;
} }
return FS_STATUS_OK; return FS_ERROR_OK;
} }
FSStatus FSWrapper::FSFlushFileWrapper(FSFileHandle handle) { FSError FSWrapper::FSFlushFileWrapper(FSFileHandle handle) {
if (!isValidFileHandle(handle)) { if (!isValidFileHandle(handle)) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
if (!pIsWriteable) { if (!pIsWriteable) {
DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to fsync fd %d (handle %08X)) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] Tried to fsync fd %d (handle %08X)) but layer is not writeable", getName().c_str(), getFileFromHandle(handle)->fd, handle);
return FS_STATUS_ACCESS_ERROR; return FS_ERROR_ACCESS_ERROR;
} }
auto fileHandle = getFileFromHandle(handle); auto fileHandle = getFileFromHandle(handle);
int real_fd = fileHandle->fd; int real_fd = fileHandle->fd;
DEBUG_FUNCTION_LINE_VERBOSE("[%s] fsync fd %08X (FSFileHandle %08X)", real_fd, handle); DEBUG_FUNCTION_LINE_VERBOSE("[%s] fsync fd %08X (FSFileHandle %08X)", real_fd, handle);
FSStatus result = FS_STATUS_OK; FSError result = FS_ERROR_OK;
if (fsync(real_fd) < 0) { if (fsync(real_fd) < 0) {
DEBUG_FUNCTION_LINE_ERR("[%s] fsync failed for fd %08X (FSFileHandle %08X)", getName().c_str(), real_fd, handle); DEBUG_FUNCTION_LINE_ERR("[%s] fsync failed for fd %08X (FSFileHandle %08X)", getName().c_str(), real_fd, handle);
result = FS_STATUS_MEDIA_ERROR; auto err = errno;
if (err == EBADF) {
result = FS_ERROR_INVALID_FILEHANDLE;
} else {
result = FS_ERROR_MEDIA_ERROR;
}
} }
return result; return result;
} }

View File

@ -32,68 +32,68 @@ public:
} }
} }
FSStatus FSOpenDirWrapper(const char *path, FSError FSOpenDirWrapper(const char *path,
FSDirectoryHandle *handle) override; FSDirectoryHandle *handle) override;
FSStatus FSReadDirWrapper(FSDirectoryHandle handle, FSError FSReadDirWrapper(FSDirectoryHandle handle,
FSDirectoryEntry *entry) override; FSDirectoryEntry *entry) override;
FSStatus FSCloseDirWrapper(FSDirectoryHandle handle) override; FSError FSCloseDirWrapper(FSDirectoryHandle handle) override;
FSStatus FSMakeDirWrapper(const char *path) override; FSError FSMakeDirWrapper(const char *path) override;
FSStatus FSRewindDirWrapper(FSDirectoryHandle handle) override; FSError FSRewindDirWrapper(FSDirectoryHandle handle) override;
FSStatus FSOpenFileWrapper(const char *path, FSError FSOpenFileWrapper(const char *path,
const char *mode, const char *mode,
FSFileHandle *handle) override; FSFileHandle *handle) override;
FSStatus FSCloseFileWrapper(FSFileHandle handle) override; FSError FSCloseFileWrapper(FSFileHandle handle) override;
FSStatus FSGetStatWrapper(const char *path, FSStat *stats) override; FSError FSGetStatWrapper(const char *path, FSStat *stats) override;
FSStatus FSGetStatFileWrapper(FSFileHandle handle, FSError FSGetStatFileWrapper(FSFileHandle handle,
FSStat *stats) override; FSStat *stats) override;
FSStatus FSReadFileWrapper(void *buffer, FSError FSReadFileWrapper(void *buffer,
uint32_t size,
uint32_t count,
FSFileHandle handle,
uint32_t unk1) override;
FSError FSReadFileWithPosWrapper(void *buffer,
uint32_t size,
uint32_t count,
uint32_t pos,
FSFileHandle handle,
int32_t unk1) override;
FSError FSSetPosFileWrapper(FSFileHandle handle,
uint32_t pos) override;
FSError FSGetPosFileWrapper(FSFileHandle handle,
uint32_t *pos) override;
FSError FSIsEofWrapper(FSFileHandle handle) override;
FSError FSTruncateFileWrapper(FSFileHandle handle) override;
FSError FSWriteFileWrapper(uint8_t *buffer,
uint32_t size, uint32_t size,
uint32_t count, uint32_t count,
FSFileHandle handle, FSFileHandle handle,
uint32_t unk1) override; uint32_t unk1) override;
FSStatus FSReadFileWithPosWrapper(void *buffer, FSError FSRemoveWrapper(const char *path) override;
uint32_t size,
uint32_t count,
uint32_t pos,
FSFileHandle handle,
int32_t unk1) override;
FSStatus FSSetPosFileWrapper(FSFileHandle handle, FSError FSRenameWrapper(const char *oldPath,
uint32_t pos) override; const char *newPath) override;
FSStatus FSGetPosFileWrapper(FSFileHandle handle, FSError FSFlushFileWrapper(FSFileHandle handle) override;
uint32_t *pos) override;
FSStatus FSIsEofWrapper(FSFileHandle handle) override;
FSStatus FSTruncateFileWrapper(FSFileHandle handle) override;
FSStatus FSWriteFileWrapper(uint8_t *buffer,
uint32_t size,
uint32_t count,
FSFileHandle handle,
uint32_t unk1) override;
FSStatus FSRemoveWrapper(const char *path) override;
FSStatus FSRenameWrapper(const char *oldPath,
const char *newPath) override;
FSStatus FSFlushFileWrapper(FSFileHandle handle) override;
protected: protected:
virtual bool IsFileModeAllowed(const char *mode); virtual bool IsFileModeAllowed(const char *mode);

View File

@ -6,13 +6,19 @@
#include <coreinit/filesystem.h> #include <coreinit/filesystem.h>
#include <filesystem> #include <filesystem>
FSStatus FSWrapperMergeDirsWithParent::FSOpenDirWrapper(const char *path, FSError FSWrapperMergeDirsWithParent::FSOpenDirWrapper(const char *path,
FSDirectoryHandle *handle) { FSDirectoryHandle *handle) {
if (handle == nullptr) {
DEBUG_FUNCTION_LINE_ERR("[%s] handle was NULL", getName().c_str());
return FS_ERROR_INVALID_PARAM;
}
auto res = FSWrapper::FSOpenDirWrapper(path, handle); auto res = FSWrapper::FSOpenDirWrapper(path, handle);
if (res == FS_STATUS_OK) { if (res == FS_ERROR_OK) {
if (handle == nullptr || !isValidDirHandle(*handle)) { if (!isValidDirHandle(*handle)) {
FSWrapper::FSCloseDirWrapper(*handle);
DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), *handle); DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), *handle);
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_DIRHANDLE;
} }
auto dirHandle = getDirExFromHandle(*handle); auto dirHandle = getDirExFromHandle(*handle);
if (dirHandle != nullptr) { if (dirHandle != nullptr) {
@ -42,16 +48,16 @@ bool FSWrapperMergeDirsWithParent::SkipDeletedFilesInReadDir() {
return false; return false;
} }
FSStatus FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry *entry) { FSError FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSDirectoryHandle handle, FSDirectoryEntry *entry) {
do { do {
auto res = FSWrapper::FSReadDirWrapper(handle, entry); auto res = FSWrapper::FSReadDirWrapper(handle, entry);
if (res == FS_STATUS_OK || res == FS_STATUS_END) { if (res == FS_ERROR_OK || res == FS_ERROR_END_OF_DIR) {
if (!isValidDirHandle(handle)) { if (!isValidDirHandle(handle)) {
DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), handle); DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), handle);
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_DIRHANDLE;
} }
auto dirHandle = getDirExFromHandle(handle); auto dirHandle = getDirExFromHandle(handle);
if (res == FS_STATUS_OK) { if (res == FS_ERROR_OK) {
if (dirHandle->readResultCapacity == 0) { if (dirHandle->readResultCapacity == 0) {
dirHandle->readResult = (FSDirectoryEntryEx *) malloc(sizeof(FSDirectoryEntryEx)); dirHandle->readResult = (FSDirectoryEntryEx *) malloc(sizeof(FSDirectoryEntryEx));
if (dirHandle->readResult == nullptr) { if (dirHandle->readResult == nullptr) {
@ -75,7 +81,7 @@ FSStatus FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSDirectoryHandle handle
dirHandle->readResultNumberOfEntries++; dirHandle->readResultNumberOfEntries++;
/** /**
* Read the next entry if this enntry starts with deletePrefix. We keep the entry but mark it as deleted. * Read the next entry if this entry starts with deletePrefix. We keep the entry but mark it as deleted.
*/ */
if (std::string_view(entry->name).starts_with(deletePrefix)) { if (std::string_view(entry->name).starts_with(deletePrefix)) {
dirHandle->readResult[dirHandle->readResultNumberOfEntries].isMarkedAsDeleted = true; dirHandle->readResult[dirHandle->readResultNumberOfEntries].isMarkedAsDeleted = true;
@ -86,7 +92,7 @@ FSStatus FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSDirectoryHandle handle
OSMemoryBarrier(); OSMemoryBarrier();
} else if (res == FS_STATUS_END) { } else if (res == FS_ERROR_END_OF_DIR) {
// Read the real directory. // Read the real directory.
if (dirHandle->realDirHandle != 0) { if (dirHandle->realDirHandle != 0) {
if (pFSClient && pCmdBlock) { if (pFSClient && pCmdBlock) {
@ -115,15 +121,15 @@ FSStatus FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSDirectoryHandle handle
// If it's new we can use it :) // If it's new we can use it :)
if (!found) { if (!found) {
memcpy(entry, &realDirEntry, sizeof(FSDirectoryEntry)); memcpy(entry, &realDirEntry, sizeof(FSDirectoryEntry));
res = FS_STATUS_OK; res = FS_ERROR_OK;
break; break;
} }
} else if (readDirResult == FS_STATUS_END) { } else if (readDirResult == FS_STATUS_END) {
res = FS_STATUS_END; res = FS_ERROR_END_OF_DIR;
break; break;
} else { } else {
DEBUG_FUNCTION_LINE_ERR("[%s] real_FSReadDir returned an unexpected error: %08X", getName().c_str(), readDirResult); DEBUG_FUNCTION_LINE_ERR("[%s] real_FSReadDir returned an unexpected error: %08X", getName().c_str(), readDirResult);
res = FS_STATUS_END; res = FS_ERROR_END_OF_DIR;
break; break;
} }
} }
@ -139,13 +145,13 @@ FSStatus FSWrapperMergeDirsWithParent::FSReadDirWrapper(FSDirectoryHandle handle
} while (true); } while (true);
} }
FSStatus FSWrapperMergeDirsWithParent::FSCloseDirWrapper(FSDirectoryHandle handle) { FSError FSWrapperMergeDirsWithParent::FSCloseDirWrapper(FSDirectoryHandle handle) {
auto res = FSWrapper::FSCloseDirWrapper(handle); auto res = FSWrapper::FSCloseDirWrapper(handle);
if (res == FS_STATUS_OK) { if (res == FS_ERROR_OK) {
if (!isValidDirHandle(handle)) { if (!isValidDirHandle(handle)) {
DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), handle); DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), handle);
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_DIRHANDLE;
} }
auto dirHandle = getDirExFromHandle(handle); auto dirHandle = getDirExFromHandle(handle);
if (dirHandle->realDirHandle != 0) { if (dirHandle->realDirHandle != 0) {
@ -156,7 +162,7 @@ FSStatus FSWrapperMergeDirsWithParent::FSCloseDirWrapper(FSDirectoryHandle handl
dirHandle->realDirHandle = 0; dirHandle->realDirHandle = 0;
} else { } else {
DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close realDirHandle %d: res %d", getName().c_str(), dirHandle->realDirHandle, realResult); DEBUG_FUNCTION_LINE_ERR("[%s] Failed to close realDirHandle %d: res %d", getName().c_str(), dirHandle->realDirHandle, realResult);
return realResult; return realResult == FS_STATUS_CANCELLED ? FS_ERROR_CANCELLED : FS_ERROR_MEDIA_ERROR;
} }
} else { } else {
DEBUG_FUNCTION_LINE_ERR("[%s] Global FSClient or FSCmdBlock were null", getName().c_str()); DEBUG_FUNCTION_LINE_ERR("[%s] Global FSClient or FSCmdBlock were null", getName().c_str());
@ -175,12 +181,12 @@ FSStatus FSWrapperMergeDirsWithParent::FSCloseDirWrapper(FSDirectoryHandle handl
return res; return res;
} }
FSStatus FSWrapperMergeDirsWithParent::FSRewindDirWrapper(FSDirectoryHandle handle) { FSError FSWrapperMergeDirsWithParent::FSRewindDirWrapper(FSDirectoryHandle handle) {
auto res = FSWrapper::FSRewindDirWrapper(handle); auto res = FSWrapper::FSRewindDirWrapper(handle);
if (res == FS_STATUS_OK) { if (res == FS_ERROR_OK) {
if (!isValidDirHandle(handle)) { if (!isValidDirHandle(handle)) {
DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), handle); DEBUG_FUNCTION_LINE_ERR("[%s] No valid dir handle %08X", getName().c_str(), handle);
return FS_STATUS_FATAL_ERROR; return FS_ERROR_INVALID_DIRHANDLE;
} }
auto dirHandle = getDirExFromHandle(handle); auto dirHandle = getDirExFromHandle(handle);
if (dirHandle->readResult != nullptr) { if (dirHandle->readResult != nullptr) {

View File

@ -13,15 +13,15 @@ public:
~FSWrapperMergeDirsWithParent() override; ~FSWrapperMergeDirsWithParent() override;
FSStatus FSOpenDirWrapper(const char *path, FSError FSOpenDirWrapper(const char *path,
FSDirectoryHandle *handle) override; FSDirectoryHandle *handle) override;
FSStatus FSReadDirWrapper(FSDirectoryHandle handle, FSError FSReadDirWrapper(FSDirectoryHandle handle,
FSDirectoryEntry *entry) override; FSDirectoryEntry *entry) override;
FSStatus FSCloseDirWrapper(FSDirectoryHandle handle) override; FSError FSCloseDirWrapper(FSDirectoryHandle handle) override;
FSStatus FSRewindDirWrapper(FSDirectoryHandle handle) override; FSError FSRewindDirWrapper(FSDirectoryHandle handle) override;
std::shared_ptr<DirInfo> getNewDirHandle() override; std::shared_ptr<DirInfo> getNewDirHandle() override;

View File

@ -5,6 +5,7 @@
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/filesystem_fsa.h>
#include <coreinit/thread.h> #include <coreinit/thread.h>
#include <map> #include <map>
#include <unistd.h> #include <unistd.h>
@ -54,11 +55,12 @@ void clearFSLayer() {
// FUN_0204cc20 // FUN_0204cc20
#define fsClientHandleFatalErrorAndBlock ((void (*)(FSClientBody *, uint32_t))(0x101C400 + 0x4cc20)) #define fsClientHandleFatalErrorAndBlock ((void (*)(FSClientBody *, uint32_t))(0x101C400 + 0x4cc20))
#define fsaDecodeFsaStatusToFsStatus ((FSStatus(*)(FSError))(0x101C400 + 0x4b148))
FSStatus doForLayer(FSClient *client, FSStatus doForLayer(FSClient *client,
FSErrorFlag errorMask, FSErrorFlag errorMask,
const std::function<FSStatus(FSErrorFlag errorMask)> &real_function, const std::function<FSStatus(FSErrorFlag errorMask)> &real_function,
const std::function<FSStatus(std::unique_ptr<IFSWrapper> &layer)> &layer_callback, const std::function<FSError(std::unique_ptr<IFSWrapper> &layer)> &layer_callback,
const std::function<FSStatus(std::unique_ptr<IFSWrapper> &layer, FSStatus)> &result_handler) { const std::function<FSStatus(std::unique_ptr<IFSWrapper> &layer, FSStatus)> &result_handler) {
FSErrorFlag realErrorMask = errorMask; FSErrorFlag realErrorMask = errorMask;
@ -79,17 +81,16 @@ FSStatus doForLayer(FSClient *client,
if (!layer->isActive()) { if (!layer->isActive()) {
continue; continue;
} }
auto result = layer_callback(layer); FSError layerResult = layer_callback(layer);
if (layerResult != FS_ERROR_FORCE_PARENT_LAYER) {
auto maskedResult = (FSError) ((layerResult & FS_ERROR_REAL_MASK) | FS_ERROR_EXTRA_MASK);
auto result = layerResult >= 0 ? static_cast<FSStatus>(layerResult) : fsaDecodeFsaStatusToFsStatus(maskedResult);
if (result != FS_STATUS_FORCE_PARENT_LAYER) {
if (result < FS_STATUS_OK && result != FS_STATUS_END && result != FS_STATUS_CANCELLED) { if (result < FS_STATUS_OK && result != FS_STATUS_END && result != FS_STATUS_CANCELLED) {
if (layer->fallbackOnError()) { if (layer->fallbackOnError()) {
// Only fallback if FS_STATUS_FORCE_NO_FALLBACK flag is not set. // Only fallback if FS_ERROR_FORCE_NO_FALLBACK flag is not set.
if (static_cast<FSStatus>(result & 0xFFFF0000) != FS_STATUS_FORCE_NO_FALLBACK) { if (static_cast<FSError>(layerResult & FS_ERROR_EXTRA_MASK) != FS_ERROR_FORCE_NO_FALLBACK) {
continue; continue;
} else {
// Remove FS_STATUS_FORCE_NO_FALLBACK flag.
result = static_cast<FSStatus>((result & 0x0000FFFF) | 0xFFFF0000);
} }
} }
} }
@ -102,7 +103,7 @@ FSStatus doForLayer(FSClient *client,
FSErrorFlag errorFlags = FS_ERROR_FLAG_NONE; FSErrorFlag errorFlags = FS_ERROR_FLAG_NONE;
bool forceError = false; bool forceError = false;
switch ((int) result) { switch ((int32_t) result) {
case FS_STATUS_MAX: case FS_STATUS_MAX:
errorFlags = FS_ERROR_FLAG_MAX; errorFlags = FS_ERROR_FLAG_MAX;
break; break;

View File

@ -45,7 +45,7 @@ void setWorkingDir(FSClient *client, const char *path);
FSStatus doForLayer(FSClient *client, FSStatus doForLayer(FSClient *client,
FSErrorFlag errorMask, FSErrorFlag errorMask,
const std::function<FSStatus(FSErrorFlag errorMask)> &real_function, const std::function<FSStatus(FSErrorFlag errorMask)> &real_function,
const std::function<FSStatus(std::unique_ptr<IFSWrapper> &layer)> &layer_callback, const std::function<FSError(std::unique_ptr<IFSWrapper> &layer)> &layer_callback,
const std::function<FSStatus(std::unique_ptr<IFSWrapper> &layer, FSStatus)> &result_handler); const std::function<FSStatus(std::unique_ptr<IFSWrapper> &layer, FSStatus)> &result_handler);
FSCmdBlockBody *fsCmdBlockGetBody(FSCmdBlock *cmdBlock); FSCmdBlockBody *fsCmdBlockGetBody(FSCmdBlock *cmdBlock);

View File

@ -3,8 +3,10 @@
#include <functional> #include <functional>
#include <string> #include <string>
#define FS_STATUS_FORCE_PARENT_LAYER (FSStatus) 0xFFFF0000 #define FS_ERROR_EXTRA_MASK 0xFFF00000
#define FS_STATUS_FORCE_NO_FALLBACK (FSStatus) 0xFFFE0000 #define FS_ERROR_REAL_MASK 0x000FFFFF
#define FS_ERROR_FORCE_PARENT_LAYER (FSError) 0xFFE0000
#define FS_ERROR_FORCE_NO_FALLBACK (FSError) 0xFFD0000
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wunused-parameter"
@ -12,104 +14,104 @@
class IFSWrapper { class IFSWrapper {
public: public:
virtual ~IFSWrapper() = default; virtual ~IFSWrapper() = default;
virtual FSStatus FSOpenDirWrapper(const char *path, virtual FSError FSOpenDirWrapper(const char *path,
FSDirectoryHandle *handle) { FSDirectoryHandle *handle) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSReadDirWrapper(FSDirectoryHandle handle, virtual FSError FSReadDirWrapper(FSDirectoryHandle handle,
FSDirectoryEntry *entry) { FSDirectoryEntry *entry) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSCloseDirWrapper(FSDirectoryHandle handle) { virtual FSError FSCloseDirWrapper(FSDirectoryHandle handle) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSRewindDirWrapper(FSDirectoryHandle handle) { virtual FSError FSRewindDirWrapper(FSDirectoryHandle handle) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSMakeDirWrapper(const char *path) { virtual FSError FSMakeDirWrapper(const char *path) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSOpenFileWrapper(const char *path, virtual FSError FSOpenFileWrapper(const char *path,
const char *mode, const char *mode,
FSFileHandle *handle) { FSFileHandle *handle) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSCloseFileWrapper(FSFileHandle handle) { virtual FSError FSCloseFileWrapper(FSFileHandle handle) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSGetStatWrapper(const char *path, virtual FSError FSGetStatWrapper(const char *path,
FSStat *stats) { FSStat *stats) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSGetStatFileWrapper(FSFileHandle handle, virtual FSError FSGetStatFileWrapper(FSFileHandle handle,
FSStat *stats) { FSStat *stats) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSReadFileWrapper(void *buffer, virtual FSError FSReadFileWrapper(void *buffer,
uint32_t size,
uint32_t count,
FSFileHandle handle,
uint32_t unk1) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
virtual FSError FSReadFileWithPosWrapper(void *buffer,
uint32_t size,
uint32_t count,
uint32_t pos,
FSFileHandle handle,
int32_t unk1) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
virtual FSError FSSetPosFileWrapper(FSFileHandle handle,
uint32_t pos) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
virtual FSError FSGetPosFileWrapper(FSFileHandle handle,
uint32_t *pos) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
virtual FSError FSIsEofWrapper(FSFileHandle handle) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
virtual FSError FSTruncateFileWrapper(FSFileHandle handle) {
return FS_ERROR_FORCE_PARENT_LAYER;
}
virtual FSError FSWriteFileWrapper(uint8_t *buffer,
uint32_t size, uint32_t size,
uint32_t count, uint32_t count,
FSFileHandle handle, FSFileHandle handle,
uint32_t unk1) { uint32_t unk1) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSReadFileWithPosWrapper(void *buffer, virtual FSError FSRemoveWrapper(const char *path) {
uint32_t size, return FS_ERROR_FORCE_PARENT_LAYER;
uint32_t count,
uint32_t pos,
FSFileHandle handle,
int32_t unk1) {
return FS_STATUS_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSSetPosFileWrapper(FSFileHandle handle, virtual FSError FSRenameWrapper(const char *oldPath,
uint32_t pos) { const char *newPath) {
return FS_STATUS_FORCE_PARENT_LAYER; return FS_ERROR_FORCE_PARENT_LAYER;
} }
virtual FSStatus FSGetPosFileWrapper(FSFileHandle handle, virtual FSError FSFlushFileWrapper(FSFileHandle handle) {
uint32_t *pos) { return FS_ERROR_FORCE_PARENT_LAYER;
return FS_STATUS_FORCE_PARENT_LAYER;
}
virtual FSStatus FSIsEofWrapper(FSFileHandle handle) {
return FS_STATUS_FORCE_PARENT_LAYER;
}
virtual FSStatus FSTruncateFileWrapper(FSFileHandle handle) {
return FS_STATUS_FORCE_PARENT_LAYER;
}
virtual FSStatus FSWriteFileWrapper(uint8_t *buffer,
uint32_t size,
uint32_t count,
FSFileHandle handle,
uint32_t unk1) {
return FS_STATUS_FORCE_PARENT_LAYER;
}
virtual FSStatus FSRemoveWrapper(const char *path) {
return FS_STATUS_FORCE_PARENT_LAYER;
}
virtual FSStatus FSRenameWrapper(const char *oldPath,
const char *newPath) {
return FS_STATUS_FORCE_PARENT_LAYER;
}
virtual FSStatus FSFlushFileWrapper(FSFileHandle handle) {
return FS_STATUS_FORCE_PARENT_LAYER;
} }
virtual bool fallbackOnError() { virtual bool fallbackOnError() {