mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-08-09 00:49:29 +02:00
Results: Implement namespaced, type-safe results.
Because I was working on multiple things at once, this commit also: - Adds wrappers for/linker flags to wrap CXX exceptions to make them abort. This saves ~0x8000 of memory in every system module. - Broadly replaces lines of the pattern if (cond) { return ResultX; } with R_UNLESS(!cond, ResultX());. - Reworks the R_TRY_CATCH macros (and the result macros in general).
This commit is contained in:
parent
1e8b13ac07
commit
15def4ef63
2
Makefile
2
Makefile
@ -16,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
||||
# INCLUDES is a list of directories containing header files
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
SOURCES := source source/ams source/os source/os/impl source/dd source/sf source/sf/cmif source/sf/hipc source/dmnt source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb source/boot2
|
||||
SOURCES := source source/ams source/result source/os source/os/impl source/dd source/sf source/sf/cmif source/sf/hipc source/dmnt source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb source/boot2
|
||||
DATA := data
|
||||
INCLUDES := include
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace sts::ams {
|
||||
const u32 build_version = GetVersion(ATMOSPHERE_RELEASE_VERSION);
|
||||
|
||||
if (runtime_version < build_version) {
|
||||
R_ASSERT(ResultAtmosphereVersionMismatch);
|
||||
R_ASSERT(ams::ResultVersionMismatch());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
cls& operator=(cls&&) = delete
|
||||
|
||||
#define ALIGNED(algn) __attribute__((aligned(algn)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
|
||||
|
@ -320,7 +320,7 @@ namespace sts::fatal {
|
||||
namespace srv {
|
||||
|
||||
struct ThrowContext {
|
||||
u32 error_code;
|
||||
Result result;
|
||||
ncm::TitleId title_id;
|
||||
char proc_name[0xD];
|
||||
bool is_creport;
|
||||
@ -332,7 +332,16 @@ namespace sts::fatal {
|
||||
u8 stack_dump[0x100];
|
||||
|
||||
void ClearState() {
|
||||
std::memset(this, 0, sizeof(*this));
|
||||
this->result = ResultSuccess();
|
||||
this->title_id = ncm::TitleId::Invalid;
|
||||
std::memset(this->proc_name, 0, sizeof(this->proc_name));
|
||||
this->is_creport = false;
|
||||
std::memset(&this->cpu_ctx, 0, sizeof(this->cpu_ctx));
|
||||
this->generate_error_report = false;
|
||||
std::memset(&this->erpt_event, 0, sizeof(this->erpt_event));
|
||||
std::memset(&this->battery_event, 0, sizeof(this->battery_event));
|
||||
this->stack_dump_size = 0;
|
||||
std::memset(this->stack_dump, 0, sizeof(this->stack_dump));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -73,10 +73,10 @@ namespace sts::kvdb {
|
||||
/* Allocate a buffer. */
|
||||
this->buffer = static_cast<u8 *>(std::malloc(size));
|
||||
if (this->buffer == nullptr) {
|
||||
return ResultKvdbAllocationFailed;
|
||||
return ResultAllocationFailed();
|
||||
}
|
||||
this->size = size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Initialize(const void *buf, size_t size) {
|
||||
@ -86,7 +86,7 @@ namespace sts::kvdb {
|
||||
/* Copy the input data in. */
|
||||
std::memcpy(this->buffer, buf, size);
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
};
|
||||
}
|
@ -56,7 +56,7 @@ namespace sts::kvdb {
|
||||
return fsdevGetLastResult();
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
private:
|
||||
void RemoveIndex(size_t i) {
|
||||
@ -105,7 +105,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Save() {
|
||||
@ -129,7 +129,7 @@ namespace sts::kvdb {
|
||||
/* Flush. */
|
||||
fflush(fp);
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
size_t GetCount() const {
|
||||
@ -235,7 +235,7 @@ namespace sts::kvdb {
|
||||
R_CATCH(ResultFsPathNotFound) {
|
||||
/* If the path doesn't exist, nothing has gone wrong. */
|
||||
*out = false;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
@ -246,7 +246,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
*out = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
static Result DirectoryExists(bool *out, const char *path) {
|
||||
@ -264,7 +264,7 @@ namespace sts::kvdb {
|
||||
return fsdevGetLastResult();
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
static Result ValidateExistingCache(const char *dir) {
|
||||
@ -283,7 +283,7 @@ namespace sts::kvdb {
|
||||
return ResultKvdbInvalidFilesystemState;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
private:
|
||||
void RemoveOldestKey() {
|
||||
@ -305,7 +305,7 @@ namespace sts::kvdb {
|
||||
/* layout it can't really be fixed without breaking existing devices... */
|
||||
R_TRY(this->kvs.Initialize(dir));
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
size_t GetCount() const {
|
||||
@ -380,7 +380,7 @@ namespace sts::kvdb {
|
||||
/* Save the list. */
|
||||
R_TRY(this->lru_list.Save());
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
@ -394,7 +394,7 @@ namespace sts::kvdb {
|
||||
R_TRY(this->kvs.Remove(key));
|
||||
R_TRY(this->lru_list.Save());
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result RemoveAll() {
|
||||
@ -404,7 +404,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
R_TRY(this->lru_list.Save());
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -97,7 +97,7 @@ namespace sts::kvdb {
|
||||
size_t size = 0;
|
||||
R_TRY(this->Get(&size, out_value, sizeof(Value), key));
|
||||
STS_ASSERT(size >= sizeof(Value));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
|
@ -128,7 +128,7 @@ namespace sts::kvdb {
|
||||
return ResultKvdbAllocationFailed;
|
||||
}
|
||||
this->capacity = capacity;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Set(const Key &key, const void *value, size_t value_size) {
|
||||
@ -156,7 +156,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Save the new Entry in the map. */
|
||||
*it = Entry(key, new_value, value_size);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result AddUnsafe(const Key &key, void *value, size_t value_size) {
|
||||
@ -165,7 +165,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
this->entries[this->count++] = Entry(key, value, value_size);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Remove(const Key &key) {
|
||||
@ -178,7 +178,7 @@ namespace sts::kvdb {
|
||||
std::free(it->GetValuePointer());
|
||||
std::memmove(it, it + 1, sizeof(*it) * (this->end() - (it + 1)));
|
||||
this->count--;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* If it's not, we didn't remove it. */
|
||||
@ -292,7 +292,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Initialize our index. */
|
||||
R_TRY(this->index.Initialize(capacity));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Initialize(size_t capacity) {
|
||||
@ -303,7 +303,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Initialize our index. */
|
||||
R_TRY(this->index.Initialize(capacity));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
size_t GetCount() const {
|
||||
@ -323,7 +323,7 @@ namespace sts::kvdb {
|
||||
AutoBuffer buffer;
|
||||
R_TRY_CATCH(this->ReadArchiveFile(&buffer)) {
|
||||
R_CATCH(ResultFsPathNotFound) {
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
@ -356,7 +356,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Save() {
|
||||
@ -406,7 +406,7 @@ namespace sts::kvdb {
|
||||
size_t size = std::min(max_out_size, it->GetValueSize());
|
||||
std::memcpy(out_value, it->GetValuePointer(), size);
|
||||
*out_size = size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<typename Value = void>
|
||||
@ -418,7 +418,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
*out_value = it->template GetValuePointer<Value>();
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<typename Value = void>
|
||||
@ -430,7 +430,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
*out_value = it->template GetValuePointer<Value>();
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<typename Value>
|
||||
@ -442,7 +442,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
*out_value = it->template GetValue<Value>();
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetValueSize(size_t *out_size, const Key &key) const {
|
||||
@ -453,7 +453,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
*out_size = it->GetValueSize();
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Remove(const Key &key) {
|
||||
@ -528,7 +528,7 @@ namespace sts::kvdb {
|
||||
return fsdevGetLastResult();
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
size_t GetArchiveSize() const {
|
||||
@ -560,7 +560,7 @@ namespace sts::kvdb {
|
||||
return fsdevGetLastResult();
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace sts::os {
|
||||
Result Join() {
|
||||
R_TRY(threadWaitForExit(&this->thr));
|
||||
R_TRY(threadClose(&this->thr));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CancelSynchronization() {
|
||||
@ -92,7 +92,7 @@ namespace sts::os {
|
||||
Result Join() {
|
||||
R_TRY(threadWaitForExit(&this->thr));
|
||||
R_TRY(threadClose(&this->thr));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CancelSynchronization() {
|
||||
|
@ -17,9 +17,10 @@
|
||||
#pragma once
|
||||
|
||||
/* Utilities. */
|
||||
#include "results/utilities.h"
|
||||
#include "results/results_common.hpp"
|
||||
|
||||
/* Official. */
|
||||
#include "results/cal_results.hpp"
|
||||
#include "results/creport_results.hpp"
|
||||
#include "results/debug_results.hpp"
|
||||
#include "results/dmnt_results.hpp"
|
||||
@ -28,7 +29,6 @@
|
||||
#include "results/fs_results.hpp"
|
||||
#include "results/hipc_results.hpp"
|
||||
#include "results/i2c_results.hpp"
|
||||
#include "results/kernel_results.hpp"
|
||||
#include "results/kvdb_results.hpp"
|
||||
#include "results/loader_results.hpp"
|
||||
#include "results/lr_results.hpp"
|
||||
@ -40,10 +40,9 @@
|
||||
#include "results/sf_results.hpp"
|
||||
#include "results/sm_results.hpp"
|
||||
#include "results/spl_results.hpp"
|
||||
#include "results/svc_results.hpp"
|
||||
#include "results/updater_results.hpp"
|
||||
#include "results/vi_results.hpp"
|
||||
|
||||
/* Unofficial. */
|
||||
#include "results/ams_results.hpp"
|
||||
|
||||
static constexpr Result ResultSuccess = 0;
|
||||
|
@ -15,17 +15,24 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
/* Please note: These results are all custom, and not official. */
|
||||
namespace sts::ams {
|
||||
|
||||
static constexpr u32 Module_Atmosphere = 444;
|
||||
/* Please note: These results are all custom, and not official. */
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(444);
|
||||
|
||||
/* Result 1-1000 reserved for Atmosphere. */
|
||||
static constexpr Result ResultAtmosphereExosphereNotPresent = MAKERESULT(Module_Atmosphere, 1);
|
||||
static constexpr Result ResultAtmosphereVersionMismatch = MAKERESULT(Module_Atmosphere, 2);
|
||||
|
||||
/* Results 1000-2000 reserved for Atmosphere Mitm. */
|
||||
static constexpr Result ResultAtmosphereMitmShouldForwardToSession = MAKERESULT(Module_Atmosphere, 1000);
|
||||
static constexpr Result ResultAtmosphereMitmProcessNotAssociated = MAKERESULT(Module_Atmosphere, 1100);
|
||||
/* Result 1-1000 reserved for Atmosphere. */
|
||||
R_DEFINE_ERROR_RESULT(ExosphereNotPresent, 1);
|
||||
R_DEFINE_ERROR_RESULT(VersionMismatch, 2);
|
||||
|
||||
/* Results 1000-2000 reserved for Atmosphere Mitm. */
|
||||
namespace mitm {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ShouldForwardToSession, 1000);
|
||||
R_DEFINE_ERROR_RESULT(ProcessNotAssociated, 1100);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
26
include/stratosphere/results/cal_results.hpp
Normal file
26
include/stratosphere/results/cal_results.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace sts::cal {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(198);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(CalibrationDataCrcError, 101);
|
||||
|
||||
}
|
@ -15,19 +15,23 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Creport = 168;
|
||||
namespace sts::creport {
|
||||
|
||||
static constexpr Result ResultCreportUndefinedInstruction = MAKERESULT(Module_Creport, 0);
|
||||
static constexpr Result ResultCreportInstructionAbort = MAKERESULT(Module_Creport, 1);
|
||||
static constexpr Result ResultCreportDataAbort = MAKERESULT(Module_Creport, 2);
|
||||
static constexpr Result ResultCreportAlignmentFault = MAKERESULT(Module_Creport, 3);
|
||||
static constexpr Result ResultCreportDebuggerAttached = MAKERESULT(Module_Creport, 4);
|
||||
static constexpr Result ResultCreportBreakPoint = MAKERESULT(Module_Creport, 5);
|
||||
static constexpr Result ResultCreportUserBreak = MAKERESULT(Module_Creport, 6);
|
||||
static constexpr Result ResultCreportDebuggerBreak = MAKERESULT(Module_Creport, 7);
|
||||
static constexpr Result ResultCreportUndefinedSystemCall = MAKERESULT(Module_Creport, 8);
|
||||
static constexpr Result ResultCreportSystemMemoryError = MAKERESULT(Module_Creport, 9);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(168);
|
||||
|
||||
static constexpr Result ResultCreportIncompleteReport = MAKERESULT(Module_Creport, 99);
|
||||
R_DEFINE_ERROR_RESULT(UndefinedInstruction, 0);
|
||||
R_DEFINE_ERROR_RESULT(InstructionAbort, 1);
|
||||
R_DEFINE_ERROR_RESULT(DataAbort, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlignmentFault, 3);
|
||||
R_DEFINE_ERROR_RESULT(DebuggerAttached, 4);
|
||||
R_DEFINE_ERROR_RESULT(BreakPoint, 5);
|
||||
R_DEFINE_ERROR_RESULT(UserBreak, 6);
|
||||
R_DEFINE_ERROR_RESULT(DebuggerBreak, 7);
|
||||
R_DEFINE_ERROR_RESULT(UndefinedSystemCall, 8);
|
||||
R_DEFINE_ERROR_RESULT(SystemMemoryError, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(IncompleteReport, 99);
|
||||
|
||||
}
|
||||
|
@ -15,10 +15,14 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Debug = 183;
|
||||
namespace sts::dbg {
|
||||
|
||||
static constexpr Result ResultDebugCannotDebug = MAKERESULT(Module_Debug, 1);
|
||||
static constexpr Result ResultDebugAlreadyAttached = MAKERESULT(Module_Debug, 2);
|
||||
static constexpr Result ResultDebugCancelled = MAKERESULT(Module_Debug, 3);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(183);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(CannotDebug, 1);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyAttached, 2);
|
||||
R_DEFINE_ERROR_RESULT(Cancelled, 3);
|
||||
|
||||
}
|
||||
|
@ -15,24 +15,36 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Dmnt = 13;
|
||||
namespace sts::dmnt {
|
||||
|
||||
static constexpr Result ResultDmntUnknown = MAKERESULT(Module_Dmnt, 1);
|
||||
static constexpr Result ResultDmntDebuggingDisabled = MAKERESULT(Module_Dmnt, 2);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(13);
|
||||
|
||||
static constexpr Result ResultDmntCheatNotAttached = MAKERESULT(Module_Dmnt, 6500);
|
||||
static constexpr Result ResultDmntCheatNullBuffer = MAKERESULT(Module_Dmnt, 6501);
|
||||
static constexpr Result ResultDmntCheatInvalidBuffer = MAKERESULT(Module_Dmnt, 6502);
|
||||
static constexpr Result ResultDmntCheatUnknownChtId = MAKERESULT(Module_Dmnt, 6503);
|
||||
static constexpr Result ResultDmntCheatOutOfCheats = MAKERESULT(Module_Dmnt, 6504);
|
||||
static constexpr Result ResultDmntCheatInvalidCheat = MAKERESULT(Module_Dmnt, 6505);
|
||||
static constexpr Result ResultDmntCheatCannotDisableMasterCheat = MAKERESULT(Module_Dmnt, 6505);
|
||||
R_DEFINE_ERROR_RESULT(Unknown, 1);
|
||||
R_DEFINE_ERROR_RESULT(DebuggingDisabled, 2);
|
||||
|
||||
static constexpr Result ResultDmntCheatInvalidFreezeWidth = MAKERESULT(Module_Dmnt, 6600);
|
||||
static constexpr Result ResultDmntCheatAddressAlreadyFrozen = MAKERESULT(Module_Dmnt, 6601);
|
||||
static constexpr Result ResultDmntCheatAddressNotFrozen = MAKERESULT(Module_Dmnt, 6602);
|
||||
static constexpr Result ResultDmntCheatTooManyFrozenAddresses = MAKERESULT(Module_Dmnt, 6603);
|
||||
/* Atmosphere extension. */
|
||||
namespace cheat {
|
||||
|
||||
static constexpr Result ResultDmntCheatVmInvalidCondDepth = MAKERESULT(Module_Dmnt, 6700);
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(CheatError, 6500, 6599);
|
||||
R_DEFINE_ERROR_RESULT(CheatNotAttached, 6500);
|
||||
R_DEFINE_ERROR_RESULT(CheatNullBuffer, 6501);
|
||||
R_DEFINE_ERROR_RESULT(CheatInvalidBuffer, 6502);
|
||||
R_DEFINE_ERROR_RESULT(CheatUnknownId, 6503);
|
||||
R_DEFINE_ERROR_RESULT(CheatOutOfResource, 6504);
|
||||
R_DEFINE_ERROR_RESULT(CheatInvalid, 6505);
|
||||
R_DEFINE_ERROR_RESULT(CheatCannotDisable, 6506);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(FrozenAddressError, 6600, 6699);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressInvalidWidth, 6600);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressAlreadyExists, 6601);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressNotFound, 6602);
|
||||
R_DEFINE_ERROR_RESULT(FrozenAddressOutOfResource, 6603);
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(VirtualMachineError, 6700, 6799);
|
||||
R_DEFINE_ERROR_RESULT(VirtualMachineInvalidConditionDepth, 6700);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,9 +15,13 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Err = 162;
|
||||
namespace sts::err {
|
||||
|
||||
static constexpr Result ResultErrApplicationAborted = MAKERESULT(Module_Err, 1);
|
||||
static constexpr Result ResultErrSystemModuleAborted = MAKERESULT(Module_Err, 2);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(162);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ApplicationAborted, 1);
|
||||
R_DEFINE_ERROR_RESULT(SystemModuleAborted, 2);
|
||||
|
||||
}
|
||||
|
@ -15,13 +15,17 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Fatal = 163;
|
||||
namespace sts::fatal {
|
||||
|
||||
static constexpr Result ResultFatalAllocationFailed = MAKERESULT(Module_Fatal, 1);
|
||||
static constexpr Result ResultFatalNullGraphicsBuffer = MAKERESULT(Module_Fatal, 2);
|
||||
static constexpr Result ResultFatalAlreadyThrown = MAKERESULT(Module_Fatal, 3);
|
||||
static constexpr Result ResultFatalTooManyEvents = MAKERESULT(Module_Fatal, 4);
|
||||
static constexpr Result ResultFatalInRepairWithoutVolHeld = MAKERESULT(Module_Fatal, 5);
|
||||
static constexpr Result ResultFatalInRepairWithoutTimeReviserCartridge = MAKERESULT(Module_Fatal, 6);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(163);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NullGraphicsBuffer, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyThrown, 3);
|
||||
R_DEFINE_ERROR_RESULT(TooManyEvents, 4);
|
||||
R_DEFINE_ERROR_RESULT(InRepairWithoutVolHeld, 5);
|
||||
R_DEFINE_ERROR_RESULT(InRepairWithoutTimeReviserCartridge, 6);
|
||||
|
||||
}
|
||||
|
@ -15,53 +15,102 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Fs = 2;
|
||||
namespace sts::fs {
|
||||
|
||||
static constexpr Result ResultFsPathNotFound = MAKERESULT(Module_Fs, 1);
|
||||
static constexpr Result ResultFsPathAlreadyExists = MAKERESULT(Module_Fs, 2);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(2);
|
||||
|
||||
static constexpr Result ResultFsTargetLocked = MAKERESULT(Module_Fs, 7);
|
||||
static constexpr Result ResultFsDirectoryNotEmpty = MAKERESULT(Module_Fs, 8);
|
||||
R_DEFINE_ERROR_RESULT(PathNotFound, 1);
|
||||
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2);
|
||||
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceRangeStart = MAKERESULT(Module_Fs, 30);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceBisRangeStart = MAKERESULT(Module_Fs, 34);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceBisCalibration = MAKERESULT(Module_Fs, 35);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceBisSafe = MAKERESULT(Module_Fs, 36);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceBisUser = MAKERESULT(Module_Fs, 37);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceBisSystem = MAKERESULT(Module_Fs, 38);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceBisRangeEnd = MAKERESULT(Module_Fs, 39);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceSdCard = MAKERESULT(Module_Fs, 39);
|
||||
static constexpr Result ResultFsNotEnoughFreeSpaceRangeEnd = MAKERESULT(Module_Fs, 45);
|
||||
R_DEFINE_ERROR_RESULT(TargetLocked, 7);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8);
|
||||
|
||||
static constexpr Result ResultFsMountNameAlreadyExists = MAKERESULT(Module_Fs, 60);
|
||||
R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45);
|
||||
R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38);
|
||||
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39);
|
||||
|
||||
static constexpr Result ResultFsTargetNotFound = MAKERESULT(Module_Fs, 1002);
|
||||
R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60);
|
||||
|
||||
static constexpr Result ResultFsSdCardNotPresent = MAKERESULT(Module_Fs, 2001);
|
||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002);
|
||||
|
||||
static constexpr Result ResultFsNotImplemented = MAKERESULT(Module_Fs, 3001);
|
||||
static constexpr Result ResultFsOutOfRange = MAKERESULT(Module_Fs, 3005);
|
||||
R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499);
|
||||
R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);
|
||||
|
||||
static constexpr Result ResultFsAllocationFailureInDirectorySaveDataFileSystem = MAKERESULT(Module_Fs, 3321);
|
||||
static constexpr Result ResultFsAllocationFailureInSubDirectoryFileSystem = MAKERESULT(Module_Fs, 3355);
|
||||
R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999);
|
||||
|
||||
static constexpr Result ResultFsPreconditionViolation = MAKERESULT(Module_Fs, 6000);
|
||||
static constexpr Result ResultFsInvalidArgument = MAKERESULT(Module_Fs, 6001);
|
||||
static constexpr Result ResultFsInvalidPath = MAKERESULT(Module_Fs, 6002);
|
||||
static constexpr Result ResultFsTooLongPath = MAKERESULT(Module_Fs, 6003);
|
||||
static constexpr Result ResultFsInvalidCharacter = MAKERESULT(Module_Fs, 6004);
|
||||
static constexpr Result ResultFsInvalidPathFormat = MAKERESULT(Module_Fs, 6005);
|
||||
static constexpr Result ResultFsDirectoryUnobtainable = MAKERESULT(Module_Fs, 6006);
|
||||
static constexpr Result ResultFsNotNormalized = MAKERESULT(Module_Fs, 6007);
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 3001);
|
||||
R_DEFINE_ERROR_RESULT(OutOfRange, 3005);
|
||||
|
||||
static constexpr Result ResultFsInvalidOffset = MAKERESULT(Module_Fs, 6061);
|
||||
static constexpr Result ResultFsInvalidSize = MAKERESULT(Module_Fs, 6062);
|
||||
static constexpr Result ResultFsNullptrArgument = MAKERESULT(Module_Fs, 6063);
|
||||
R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355);
|
||||
|
||||
static constexpr Result ResultFsInvalidSaveDataSpaceId = MAKERESULT(Module_Fs, 6082);
|
||||
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
|
||||
|
||||
static constexpr Result ResultFsUnsupportedOperation = MAKERESULT(Module_Fs, 6300);
|
||||
R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999);
|
||||
R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299);
|
||||
R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499);
|
||||
R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599);
|
||||
R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639);
|
||||
R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659);
|
||||
R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679);
|
||||
R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719);
|
||||
R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739);
|
||||
R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759);
|
||||
R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769);
|
||||
R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779);
|
||||
|
||||
static constexpr Result ResultFsPermissionDenied = MAKERESULT(Module_Fs, 6400);
|
||||
R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499);
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199);
|
||||
R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029);
|
||||
R_DEFINE_ERROR_RESULT(TooLongPath, 6003);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005);
|
||||
R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006);
|
||||
R_DEFINE_ERROR_RESULT(NotNormalized, 6007);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 6061);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6062);
|
||||
R_DEFINE_ERROR_RESULT(NullptrArgument, 6063);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMountName, 6065);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066);
|
||||
R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299);
|
||||
R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457);
|
||||
R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461);
|
||||
R_DEFINE_ERROR_RESULT(UserNotExist, 6465);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799);
|
||||
R_DEFINE_ERROR_RESULT(MappingTableFull, 6706);
|
||||
R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899);
|
||||
R_DEFINE_ERROR_RESULT(MapFull, 6811);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(BadState, 6900, 6999);
|
||||
R_DEFINE_ERROR_RESULT(NotMounted, 6905);
|
||||
|
||||
}
|
||||
|
@ -15,23 +15,27 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Hipc = 11;
|
||||
namespace sts::sf::hipc {
|
||||
|
||||
static constexpr Result ResultHipcSessionAllocationFailure = MAKERESULT(Module_Hipc, 102);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(11);
|
||||
|
||||
static constexpr Result ResultHipcOutOfSessions = MAKERESULT(Module_Hipc, 131);
|
||||
static constexpr Result ResultHipcPointerBufferTooSmall = MAKERESULT(Module_Hipc, 141);
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(OutOfResource, 100, 299);
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessionMemory, 102);
|
||||
R_DEFINE_ERROR_RANGE (OutOfSessions, 131, 139);
|
||||
R_DEFINE_ERROR_RESULT(PointerBufferTooSmall, 141);
|
||||
|
||||
static constexpr Result ResultHipcOutOfDomains = MAKERESULT(Module_Hipc, 200);
|
||||
R_DEFINE_ERROR_RESULT(OutOfDomains, 200);
|
||||
|
||||
static constexpr Result ResultHipcSessionClosed = MAKERESULT(Module_Hipc, 301);
|
||||
R_DEFINE_ERROR_RESULT(SessionClosed, 301);
|
||||
|
||||
static constexpr Result ResultHipcInvalidRequestSize = MAKERESULT(Module_Hipc, 402);
|
||||
static constexpr Result ResultHipcUnknownCommandType = MAKERESULT(Module_Hipc, 403);
|
||||
R_DEFINE_ERROR_RESULT(InvalidRequestSize, 402);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCommandType, 403);
|
||||
|
||||
static constexpr Result ResultHipcInvalidRequest = MAKERESULT(Module_Hipc, 420);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCmifRequest, 420);
|
||||
|
||||
static constexpr Result ResultHipcTargetNotDomain = MAKERESULT(Module_Hipc, 491);
|
||||
static constexpr Result ResultHipcDomainObjectNotFound = MAKERESULT(Module_Hipc, 492);
|
||||
R_DEFINE_ERROR_RESULT(TargetNotDomain, 491);
|
||||
R_DEFINE_ERROR_RESULT(DomainObjectNotFound, 492);
|
||||
|
||||
}
|
||||
|
@ -15,12 +15,16 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_I2c = 101;
|
||||
namespace sts::i2c {
|
||||
|
||||
static constexpr Result ResultI2cNoAck = MAKERESULT(Module_I2c, 1);
|
||||
static constexpr Result ResultI2cBusBusy = MAKERESULT(Module_I2c, 2);
|
||||
static constexpr Result ResultI2cFullCommandList = MAKERESULT(Module_I2c, 3);
|
||||
static constexpr Result ResultI2cTimedOut = MAKERESULT(Module_I2c, 4);
|
||||
static constexpr Result ResultI2cUnknownDevice = MAKERESULT(Module_I2c, 5);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(101);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NoAck, 1);
|
||||
R_DEFINE_ERROR_RESULT(BusBusy, 2);
|
||||
R_DEFINE_ERROR_RESULT(FullCommandList, 3);
|
||||
R_DEFINE_ERROR_RESULT(TimedOut, 4);
|
||||
R_DEFINE_ERROR_RESULT(UnknownDevice, 5);
|
||||
|
||||
}
|
||||
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 <switch.h>
|
||||
|
||||
/* libnx already has: static constexpr u32 Module_Kernel = 1; */
|
||||
|
||||
static constexpr Result ResultKernelOutOfSessions = MAKERESULT(Module_Kernel, KernelError_OutOfSessions);
|
||||
|
||||
static constexpr Result ResultKernelInvalidCapabilityDescriptor = MAKERESULT(Module_Kernel, KernelError_InvalidCapabilityDescriptor);
|
||||
|
||||
static constexpr Result ResultKernelNotImplemented = MAKERESULT(Module_Kernel, KernelError_NotImplemented);
|
||||
static constexpr Result ResultKernelThreadTerminating = MAKERESULT(Module_Kernel, KernelError_ThreadTerminating);
|
||||
|
||||
static constexpr Result ResultKernelOutOfDebugEvents = MAKERESULT(Module_Kernel, KernelError_OutOfDebugEvents);
|
||||
|
||||
static constexpr Result ResultKernelInvalidSize = MAKERESULT(Module_Kernel, KernelError_InvalidSize);
|
||||
static constexpr Result ResultKernelInvalidAddress = MAKERESULT(Module_Kernel, KernelError_InvalidAddress);
|
||||
static constexpr Result ResultKernelResourceExhausted = MAKERESULT(Module_Kernel, KernelError_ResourceExhausted);
|
||||
static constexpr Result ResultKernelOutOfMemory = MAKERESULT(Module_Kernel, KernelError_OutOfMemory);
|
||||
static constexpr Result ResultKernelOutOfHandles = MAKERESULT(Module_Kernel, KernelError_OutOfHandles);
|
||||
static constexpr Result ResultKernelInvalidMemoryState = MAKERESULT(Module_Kernel, KernelError_InvalidMemoryState);
|
||||
static constexpr Result ResultKernelInvalidMemoryPermissions = MAKERESULT(Module_Kernel, KernelError_InvalidMemoryPermissions);
|
||||
static constexpr Result ResultKernelInvalidMemoryRange = MAKERESULT(Module_Kernel, KernelError_InvalidMemoryRange);
|
||||
static constexpr Result ResultKernelInvalidPriority = MAKERESULT(Module_Kernel, KernelError_InvalidPriority);
|
||||
static constexpr Result ResultKernelInvalidCoreId = MAKERESULT(Module_Kernel, KernelError_InvalidCoreId);
|
||||
static constexpr Result ResultKernelInvalidHandle = MAKERESULT(Module_Kernel, KernelError_InvalidHandle);
|
||||
static constexpr Result ResultKernelInvalidUserBuffer = MAKERESULT(Module_Kernel, KernelError_InvalidUserBuffer);
|
||||
static constexpr Result ResultKernelInvalidCombination = MAKERESULT(Module_Kernel, KernelError_InvalidCombination);
|
||||
static constexpr Result ResultKernelTimedOut = MAKERESULT(Module_Kernel, KernelError_TimedOut);
|
||||
static constexpr Result ResultKernelCancelled = MAKERESULT(Module_Kernel, KernelError_Cancelled);
|
||||
static constexpr Result ResultKernelOutOfRange = MAKERESULT(Module_Kernel, KernelError_OutOfRange);
|
||||
static constexpr Result ResultKernelInvalidEnumValue = MAKERESULT(Module_Kernel, KernelError_InvalidEnumValue);
|
||||
static constexpr Result ResultKernelNotFound = MAKERESULT(Module_Kernel, KernelError_NotFound);
|
||||
static constexpr Result ResultKernelAlreadyExists = MAKERESULT(Module_Kernel, KernelError_AlreadyExists);
|
||||
static constexpr Result ResultKernelConnectionClosed = MAKERESULT(Module_Kernel, KernelError_ConnectionClosed);
|
||||
static constexpr Result ResultKernelUnhandledUserInterrupt = MAKERESULT(Module_Kernel, KernelError_UnhandledUserInterrupt);
|
||||
static constexpr Result ResultKernelInvalidState = MAKERESULT(Module_Kernel, KernelError_InvalidState);
|
||||
static constexpr Result ResultKernelReservedValue = MAKERESULT(Module_Kernel, KernelError_ReservedValue);
|
||||
static constexpr Result ResultKernelInvalidHwBreakpoint = MAKERESULT(Module_Kernel, KernelError_InvalidHwBreakpoint);
|
||||
static constexpr Result ResultKernelFatalUserException = MAKERESULT(Module_Kernel, KernelError_FatalUserException);
|
||||
static constexpr Result ResultKernelOwnedByAnotherProcess = MAKERESULT(Module_Kernel, KernelError_OwnedByAnotherProcess);
|
||||
static constexpr Result ResultKernelConnectionRefused = MAKERESULT(Module_Kernel, KernelError_ConnectionRefused);
|
||||
static constexpr Result ResultKernelLimitReached = MAKERESULT(Module_Kernel, 132 /* KernelError_OutOfResource */);
|
||||
|
||||
static constexpr Result ResultKernelReceiveListBroken = MAKERESULT(Module_Kernel, 258);
|
||||
static constexpr Result ResultKernelIpcMapFailed = MAKERESULT(Module_Kernel, KernelError_IpcMapFailed);
|
||||
static constexpr Result ResultKernelIpcCmdBufTooSmall = MAKERESULT(Module_Kernel, KernelError_IpcCmdbufTooSmall);
|
||||
|
||||
static constexpr Result ResultKernelNotDebugged = MAKERESULT(Module_Kernel, KernelError_NotDebugged);
|
@ -15,15 +15,19 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Kvdb = 20;
|
||||
namespace sts::kvdb {
|
||||
|
||||
static constexpr Result ResultKvdbKeyCapacityInsufficient = MAKERESULT(Module_Kvdb, 1);
|
||||
static constexpr Result ResultKvdbKeyNotFound = MAKERESULT(Module_Kvdb, 2);
|
||||
static constexpr Result ResultKvdbAllocationFailed = MAKERESULT(Module_Kvdb, 4);
|
||||
static constexpr Result ResultKvdbInvalidKeyValue = MAKERESULT(Module_Kvdb, 5);
|
||||
static constexpr Result ResultKvdbBufferInsufficient = MAKERESULT(Module_Kvdb, 6);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(20);
|
||||
|
||||
static constexpr Result ResultKvdbInvalidFilesystemState = MAKERESULT(Module_Kvdb, 8);
|
||||
static constexpr Result ResultKvdbNotCreated = MAKERESULT(Module_Kvdb, 9);
|
||||
R_DEFINE_ERROR_RESULT(KeyCapacityInsufficient, 1);
|
||||
R_DEFINE_ERROR_RESULT(KeyNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidKeyValue, 5);
|
||||
R_DEFINE_ERROR_RESULT(BufferInsufficient, 6);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidFilesystemState, 8);
|
||||
R_DEFINE_ERROR_RESULT(NotCreated, 9);
|
||||
|
||||
}
|
||||
|
@ -15,45 +15,49 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Loader = 9;
|
||||
namespace sts::ldr {
|
||||
|
||||
static constexpr Result ResultLoaderTooLongArgument = MAKERESULT(Module_Loader, 1);
|
||||
static constexpr Result ResultLoaderTooManyArguments = MAKERESULT(Module_Loader, 2);
|
||||
static constexpr Result ResultLoaderTooLargeMeta = MAKERESULT(Module_Loader, 3);
|
||||
static constexpr Result ResultLoaderInvalidMeta = MAKERESULT(Module_Loader, 4);
|
||||
static constexpr Result ResultLoaderInvalidNso = MAKERESULT(Module_Loader, 5);
|
||||
static constexpr Result ResultLoaderInvalidPath = MAKERESULT(Module_Loader, 6);
|
||||
static constexpr Result ResultLoaderTooManyProcesses = MAKERESULT(Module_Loader, 7);
|
||||
static constexpr Result ResultLoaderNotPinned = MAKERESULT(Module_Loader, 8);
|
||||
static constexpr Result ResultLoaderInvalidProgramId = MAKERESULT(Module_Loader, 9);
|
||||
static constexpr Result ResultLoaderInvalidVersion = MAKERESULT(Module_Loader, 10);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(9);
|
||||
|
||||
static constexpr Result ResultLoaderInsufficientAddressSpace = MAKERESULT(Module_Loader, 51);
|
||||
static constexpr Result ResultLoaderInvalidNro = MAKERESULT(Module_Loader, 52);
|
||||
static constexpr Result ResultLoaderInvalidNrr = MAKERESULT(Module_Loader, 53);
|
||||
static constexpr Result ResultLoaderInvalidSignature = MAKERESULT(Module_Loader, 54);
|
||||
static constexpr Result ResultLoaderInsufficientNroRegistrations = MAKERESULT(Module_Loader, 55);
|
||||
static constexpr Result ResultLoaderInsufficientNrrRegistrations = MAKERESULT(Module_Loader, 56);
|
||||
static constexpr Result ResultLoaderNroAlreadyLoaded = MAKERESULT(Module_Loader, 57);
|
||||
R_DEFINE_ERROR_RESULT(TooLongArgument, 1);
|
||||
R_DEFINE_ERROR_RESULT(TooManyArguments, 2);
|
||||
R_DEFINE_ERROR_RESULT(TooLargeMeta, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidMeta, 4);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNso, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPath, 6);
|
||||
R_DEFINE_ERROR_RESULT(TooManyProcesses, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotPinned, 8);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProgramId, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidVersion, 10);
|
||||
|
||||
static constexpr Result ResultLoaderInvalidAddress = MAKERESULT(Module_Loader, 81);
|
||||
static constexpr Result ResultLoaderInvalidSize = MAKERESULT(Module_Loader, 82);
|
||||
static constexpr Result ResultLoaderNotLoaded = MAKERESULT(Module_Loader, 84);
|
||||
static constexpr Result ResultLoaderNotRegistered = MAKERESULT(Module_Loader, 85);
|
||||
static constexpr Result ResultLoaderInvalidSession = MAKERESULT(Module_Loader, 86);
|
||||
static constexpr Result ResultLoaderInvalidProcess = MAKERESULT(Module_Loader, 87);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientAddressSpace, 51);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNro, 52);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrr, 53);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSignature, 54);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientNroRegistrations, 55);
|
||||
R_DEFINE_ERROR_RESULT(InsufficientNrrRegistrations, 56);
|
||||
R_DEFINE_ERROR_RESULT(NroAlreadyLoaded, 57);
|
||||
|
||||
static constexpr Result ResultLoaderUnknownCapability = MAKERESULT(Module_Loader, 100);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityKernelFlags = MAKERESULT(Module_Loader, 103);
|
||||
static constexpr Result ResultLoaderInvalidCapabilitySyscallMask = MAKERESULT(Module_Loader, 104);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityMapRange = MAKERESULT(Module_Loader, 106);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityMapPage = MAKERESULT(Module_Loader, 107);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityInterruptPair = MAKERESULT(Module_Loader, 111);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityApplicationType = MAKERESULT(Module_Loader, 113);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityKernelVersion = MAKERESULT(Module_Loader, 114);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityHandleTable = MAKERESULT(Module_Loader, 115);
|
||||
static constexpr Result ResultLoaderInvalidCapabilityDebugFlags = MAKERESULT(Module_Loader, 116);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 81);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 82);
|
||||
R_DEFINE_ERROR_RESULT(NotLoaded, 84);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 85);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSession, 86);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProcess, 87);
|
||||
|
||||
static constexpr Result ResultLoaderInternalError = MAKERESULT(Module_Loader, 200);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCapability, 100);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelFlags, 103);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilitySyscallMask, 104);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityMapRange, 106);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityMapPage, 107);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityInterruptPair, 111);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityApplicationType, 113);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityKernelVersion, 114);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityHandleTable, 115);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCapabilityDebugFlags, 116);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InternalError, 200);
|
||||
|
||||
}
|
||||
|
@ -15,16 +15,20 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Lr = 8;
|
||||
namespace sts::lr {
|
||||
|
||||
static constexpr Result ResultLrProgramNotFound = MAKERESULT(Module_Lr, 2);
|
||||
static constexpr Result ResultLrDataNotFound = MAKERESULT(Module_Lr, 3);
|
||||
static constexpr Result ResultLrUnknownStorageId = MAKERESULT(Module_Lr, 4);
|
||||
static constexpr Result ResultLrHtmlDocumentNotFound = MAKERESULT(Module_Lr, 6);
|
||||
static constexpr Result ResultLrAddOnContentNotFound = MAKERESULT(Module_Lr, 7);
|
||||
static constexpr Result ResultLrControlNotFound = MAKERESULT(Module_Lr, 8);
|
||||
static constexpr Result ResultLrLegalInformationNotFound = MAKERESULT(Module_Lr, 9);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(8);
|
||||
|
||||
static constexpr Result ResultLrTooManyRegisteredPaths = MAKERESULT(Module_Lr, 90);
|
||||
R_DEFINE_ERROR_RESULT(ProgramNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(DataNotFound, 3);
|
||||
R_DEFINE_ERROR_RESULT(UnknownStorageId, 4);
|
||||
R_DEFINE_ERROR_RESULT(HtmlDocumentNotFound, 6);
|
||||
R_DEFINE_ERROR_RESULT(AddOnContentNotFound, 7);
|
||||
R_DEFINE_ERROR_RESULT(ControlNotFound, 8);
|
||||
R_DEFINE_ERROR_RESULT(LegalInformationNotFound, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TooManyRegisteredPaths, 90);
|
||||
|
||||
}
|
||||
|
@ -15,37 +15,41 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Ncm = 5;
|
||||
namespace sts::ncm {
|
||||
|
||||
static constexpr Result ResultNcmPlaceHolderAlreadyExists = MAKERESULT(Module_Ncm, 2);
|
||||
static constexpr Result ResultNcmPlaceHolderNotFound = MAKERESULT(Module_Ncm, 3);
|
||||
static constexpr Result ResultNcmContentAlreadyExists = MAKERESULT(Module_Ncm, 4);
|
||||
static constexpr Result ResultNcmContentNotFound = MAKERESULT(Module_Ncm, 5);
|
||||
static constexpr Result ResultNcmContentMetaNotFound = MAKERESULT(Module_Ncm, 7);
|
||||
static constexpr Result ResultNcmAllocationFailed = MAKERESULT(Module_Ncm, 8);
|
||||
static constexpr Result ResultNcmUnknownStorage = MAKERESULT(Module_Ncm, 12);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(5);
|
||||
|
||||
static constexpr Result ResultNcmInvalidContentStorage = MAKERESULT(Module_Ncm, 100);
|
||||
static constexpr Result ResultNcmInvalidContentMetaDatabase = MAKERESULT(Module_Ncm, 110);
|
||||
R_DEFINE_ERROR_RESULT(PlaceHolderAlreadyExists, 2);
|
||||
R_DEFINE_ERROR_RESULT(PlaceHolderNotFound, 3);
|
||||
R_DEFINE_ERROR_RESULT(ContentAlreadyExists, 4);
|
||||
R_DEFINE_ERROR_RESULT(ContentNotFound, 5);
|
||||
R_DEFINE_ERROR_RESULT(ContentMetaNotFound, 7);
|
||||
R_DEFINE_ERROR_RESULT(AllocationFailed, 8);
|
||||
R_DEFINE_ERROR_RESULT(UnknownStorage, 12);
|
||||
|
||||
static constexpr Result ResultNcmBufferInsufficient = MAKERESULT(Module_Ncm, 180);
|
||||
static constexpr Result ResultNcmInvalidContentMetaKey = MAKERESULT(Module_Ncm, 240);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentStorage, 100);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaDatabase, 110);
|
||||
|
||||
static constexpr Result ResultNcmContentStorageNotActive = MAKERESULT(Module_Ncm, 250);
|
||||
static constexpr Result ResultNcmGameCardContentStorageNotActive = MAKERESULT(Module_Ncm, 251);
|
||||
static constexpr Result ResultNcmNandSystemContentStorageNotActive = MAKERESULT(Module_Ncm, 252);
|
||||
static constexpr Result ResultNcmNandUserContentStorageNotActive = MAKERESULT(Module_Ncm, 253);
|
||||
static constexpr Result ResultNcmSdCardContentStorageNotActive = MAKERESULT(Module_Ncm, 254);
|
||||
static constexpr Result ResultNcmUnknownContentStorageNotActive = MAKERESULT(Module_Ncm, 258);
|
||||
R_DEFINE_ERROR_RESULT(BufferInsufficient, 180);
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaKey, 240);
|
||||
|
||||
static constexpr Result ResultNcmContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 260);
|
||||
static constexpr Result ResultNcmGameCardContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 261);
|
||||
static constexpr Result ResultNcmNandSystemContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 262);
|
||||
static constexpr Result ResultNcmNandUserContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 263);
|
||||
static constexpr Result ResultNcmSdCardContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 264);
|
||||
static constexpr Result ResultNcmUnknownContentMetaDatabaseNotActive = MAKERESULT(Module_Ncm, 268);
|
||||
R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251);
|
||||
R_DEFINE_ERROR_RESULT(NandSystemContentStorageNotActive, 252);
|
||||
R_DEFINE_ERROR_RESULT(NandUserContentStorageNotActive, 253);
|
||||
R_DEFINE_ERROR_RESULT(SdCardContentStorageNotActive, 254);
|
||||
R_DEFINE_ERROR_RESULT(UnknownContentStorageNotActive, 258);
|
||||
|
||||
static constexpr Result ResultNcmInvalidArgument = MAKERESULT(Module_Ncm, 8181);
|
||||
static constexpr Result ResultNcmInvalidOffset = MAKERESULT(Module_Ncm, 8182);
|
||||
R_DEFINE_ERROR_RANGE(ContentMetaDatabaseNotActive, 260, 268);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentMetaDatabaseNotActive, 261);
|
||||
R_DEFINE_ERROR_RESULT(NandSystemContentMetaDatabaseNotActive, 262);
|
||||
R_DEFINE_ERROR_RESULT(NandUserContentMetaDatabaseNotActive, 263);
|
||||
R_DEFINE_ERROR_RESULT(SdCardContentMetaDatabaseNotActive, 264);
|
||||
R_DEFINE_ERROR_RESULT(UnknownContentMetaDatabaseNotActive, 268);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 8181, 8191);
|
||||
R_DEFINE_ERROR_RESULT(InvalidOffset, 8182);
|
||||
|
||||
}
|
||||
|
@ -15,9 +15,18 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Os = 3;
|
||||
namespace sts::os {
|
||||
|
||||
static constexpr Result ResultOsOutOfMemory = MAKERESULT(Module_Os, 8);
|
||||
static constexpr Result ResultOsResourceExhausted = MAKERESULT(Module_Os, 9);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(3);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(Busy, 4);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 8);
|
||||
R_DEFINE_ERROR_RESULT(OutOfResource, 9);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfVirtualAddressSpace, 12);
|
||||
R_DEFINE_ERROR_RESULT(ResourceLimit, 13);
|
||||
|
||||
}
|
||||
|
@ -15,13 +15,17 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Pm = 15;
|
||||
namespace sts::pm {
|
||||
|
||||
static constexpr Result ResultPmProcessNotFound = MAKERESULT(Module_Pm, 1);
|
||||
static constexpr Result ResultPmAlreadyStarted = MAKERESULT(Module_Pm, 2);
|
||||
static constexpr Result ResultPmNotExited = MAKERESULT(Module_Pm, 3);
|
||||
static constexpr Result ResultPmDebugHookInUse = MAKERESULT(Module_Pm, 4);
|
||||
static constexpr Result ResultPmApplicationRunning = MAKERESULT(Module_Pm, 5);
|
||||
static constexpr Result ResultPmInvalidSize = MAKERESULT(Module_Pm, 6);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(15);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProcessNotFound, 1);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyStarted, 2);
|
||||
R_DEFINE_ERROR_RESULT(NotExited, 3);
|
||||
R_DEFINE_ERROR_RESULT(DebugHookInUse, 4);
|
||||
R_DEFINE_ERROR_RESULT(ApplicationRunning, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 6);
|
||||
|
||||
}
|
||||
|
288
include/stratosphere/results/results_common.hpp
Normal file
288
include/stratosphere/results/results_common.hpp
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 <switch.h>
|
||||
#include <climits>
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace sts {
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
class ResultTraits {
|
||||
public:
|
||||
using BaseType = u32;
|
||||
static_assert(std::is_same<BaseType, ::Result>::value, "std::is_same<BaseType, ::Result>::value");
|
||||
static constexpr BaseType SuccessValue = BaseType();
|
||||
static constexpr BaseType ModuleBits = 9;
|
||||
static constexpr BaseType DescriptionBits = 13;
|
||||
static constexpr BaseType ReservedBits = 10;
|
||||
static_assert(ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT, "ModuleBits + DescriptionBits + ReservedBits == sizeof(BaseType) * CHAR_BIT");
|
||||
public:
|
||||
NX_CONSTEXPR BaseType MakeValue(BaseType module, BaseType description) {
|
||||
return (module) | (description << ModuleBits);
|
||||
}
|
||||
|
||||
template<BaseType module, BaseType description>
|
||||
struct MakeStaticValue : public std::integral_constant<BaseType, MakeValue(module, description)> {
|
||||
static_assert(module < (1 << ModuleBits), "Invalid Module");
|
||||
static_assert(description < (1 << DescriptionBits), "Invalid Description");
|
||||
};
|
||||
|
||||
NX_CONSTEXPR BaseType GetModuleFromValue(BaseType value) {
|
||||
return value & ~(~BaseType() << ModuleBits);
|
||||
}
|
||||
|
||||
NX_CONSTEXPR BaseType GetDescriptionFromValue(BaseType value) {
|
||||
return ((value >> ModuleBits) & ~(~BaseType() << DescriptionBits));
|
||||
}
|
||||
};
|
||||
|
||||
/* Use CRTP for Results. */
|
||||
template<typename Self>
|
||||
class ResultBase {
|
||||
public:
|
||||
using BaseType = typename ResultTraits::BaseType;
|
||||
static constexpr BaseType SuccessValue = ResultTraits::SuccessValue;
|
||||
public:
|
||||
constexpr inline BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
constexpr inline BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast<const Self *>(this)->GetValue()); }
|
||||
};
|
||||
|
||||
class ResultConstructor;
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess;
|
||||
|
||||
class Result final : public result::impl::ResultBase<Result> {
|
||||
friend class ResultConstructor;
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<Result>;
|
||||
private:
|
||||
typename Base::BaseType value;
|
||||
private:
|
||||
/* TODO: Maybe one-day, the result constructor. */
|
||||
public:
|
||||
Result() { /* ... */ }
|
||||
|
||||
/* TODO: It sure would be nice to make this private. */
|
||||
constexpr Result(typename Base::BaseType v) : value(v) { static_assert(std::is_same<typename Base::BaseType, ::Result>::value); }
|
||||
|
||||
constexpr inline operator ResultSuccess() const;
|
||||
NX_CONSTEXPR bool CanAccept(Result result) { return true; }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return this->GetValue() == Base::SuccessValue; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); }
|
||||
constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return this->value; }
|
||||
};
|
||||
static_assert(sizeof(Result) == sizeof(Result::Base::BaseType), "sizeof(Result) == sizeof(Result::Base::BaseType)");
|
||||
static_assert(std::is_trivially_destructible<Result>::value, "std::is_trivially_destructible<Result>::value");
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
class ResultConstructor {
|
||||
public:
|
||||
static constexpr inline Result MakeResult(ResultTraits::BaseType value) {
|
||||
return Result(value);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr inline Result MakeResult(ResultTraits::BaseType value) {
|
||||
return ResultConstructor::MakeResult(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ResultSuccess final : public result::impl::ResultBase<ResultSuccess> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<ResultSuccess>;
|
||||
public:
|
||||
constexpr operator Result() const { return result::impl::MakeResult(Base::SuccessValue); }
|
||||
NX_CONSTEXPR bool CanAccept(Result result) { return result.IsSuccess(); }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return true; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
constexpr inline typename Base::BaseType GetModule() const { return Base::GetModule(); }
|
||||
constexpr inline typename Base::BaseType GetDescription() const { return Base::GetDescription(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return Base::SuccessValue; }
|
||||
};
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
NORETURN void OnResultAssertion(Result result);
|
||||
|
||||
}
|
||||
|
||||
constexpr inline Result::operator ResultSuccess() const {
|
||||
if (!ResultSuccess::CanAccept(*this)) {
|
||||
result::impl::OnResultAssertion(*this);
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
namespace result::impl {
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType _Description>
|
||||
class ResultErrorBase : public ResultBase<ResultErrorBase<_Module, _Description>> {
|
||||
public:
|
||||
using Base = typename result::impl::ResultBase<ResultErrorBase<_Module, _Description>>;
|
||||
static constexpr typename Base::BaseType Module = _Module;
|
||||
static constexpr typename Base::BaseType Description = _Description;
|
||||
static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue<Module, Description>::value;
|
||||
static_assert(Value != Base::SuccessValue, "Value != Base::SuccessValue");
|
||||
public:
|
||||
constexpr operator Result() const { return MakeResult(Value); }
|
||||
constexpr operator ResultSuccess() const { OnResultAssertion(Value); }
|
||||
|
||||
constexpr inline bool IsSuccess() const { return false; }
|
||||
constexpr inline bool IsFailure() const { return !this->IsSuccess(); }
|
||||
|
||||
constexpr inline typename Base::BaseType GetValue() const { return Value; }
|
||||
};
|
||||
|
||||
template<ResultTraits::BaseType _Module, ResultTraits::BaseType DescStart, ResultTraits::BaseType DescEnd>
|
||||
class ResultErrorRangeBase {
|
||||
public:
|
||||
static constexpr ResultTraits::BaseType Module = _Module;
|
||||
static constexpr ResultTraits::BaseType DescriptionStart = DescStart;
|
||||
static constexpr ResultTraits::BaseType DescriptionEnd = DescEnd;
|
||||
static_assert(DescriptionStart <= DescriptionEnd, "DescriptionStart <= DescriptionEnd");
|
||||
static constexpr typename ResultTraits::BaseType StartValue = ResultTraits::MakeStaticValue<Module, DescriptionStart>::value;
|
||||
static constexpr typename ResultTraits::BaseType EndValue = ResultTraits::MakeStaticValue<Module, DescriptionEnd>::value;
|
||||
public:
|
||||
NX_CONSTEXPR bool Includes(Result result) {
|
||||
return StartValue <= result.GetValue() && result.GetValue() <= EndValue;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Macros for defining new results. */
|
||||
#define R_DEFINE_NAMESPACE_RESULT_MODULE(value) namespace impl::result { static constexpr inline ::sts::result::impl::ResultTraits::BaseType ResultModuleId = value; }
|
||||
#define R_CURRENT_NAMESPACE_RESULT_MODULE impl::result::ResultModuleId
|
||||
#define R_NAMESPACE_MODULE_ID(nmspc) nmspc::R_CURRENT_NAMESPACE_RESULT_MODULE
|
||||
|
||||
#define R_MAKE_NAMESPACE_RESULT(nmspc, desc) static_cast<::sts::Result>(::sts::result::impl::ResultTraits::MakeValue(R_NAMESPACE_MODULE_ID(nmspc), desc))
|
||||
|
||||
#define R_DEFINE_ERROR_RESULT_IMPL(name, desc_start, desc_end) \
|
||||
class Result##name final : public ::sts::result::impl::ResultErrorBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start>, public ::sts::result::impl::ResultErrorRangeBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start, desc_end> {}
|
||||
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc_start, desc_end) \
|
||||
class Result##name final : public ::sts::result::impl::ResultErrorRangeBase<R_CURRENT_NAMESPACE_RESULT_MODULE, desc_start, desc_end> {}
|
||||
|
||||
|
||||
#define R_DEFINE_ERROR_RESULT(name, desc) R_DEFINE_ERROR_RESULT_IMPL(name, desc, desc)
|
||||
#define R_DEFINE_ERROR_RANGE(name, start, end) R_DEFINE_ERROR_RESULT_IMPL(name, start, end)
|
||||
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RESULT(name, desc) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, desc, desc)
|
||||
#define R_DEFINE_ABSTRACT_ERROR_RANGE(name, start, end) R_DEFINE_ABSTRACT_ERROR_RESULT_IMPL(name, start, end)
|
||||
|
||||
/* Remove libnx macros, replace with our own. */
|
||||
#ifndef R_SUCCEEDED
|
||||
#error "R_SUCCEEDED not defined."
|
||||
#endif
|
||||
|
||||
#undef R_SUCCEEDED
|
||||
|
||||
#ifndef R_FAILED
|
||||
#error "R_FAILED not defined"
|
||||
#endif
|
||||
|
||||
#undef R_FAILED
|
||||
|
||||
#define R_SUCCEEDED(res) (static_cast<::sts::Result>(res).IsSuccess())
|
||||
#define R_FAILED(res) (static_cast<::sts::Result>(res).IsFailure())
|
||||
|
||||
|
||||
/// Evaluates an expression that returns a result, and returns the result if it would fail.
|
||||
#define R_TRY(res_expr) \
|
||||
({ \
|
||||
const auto _tmp_r_try_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_try_rc)) { \
|
||||
return _tmp_r_try_rc; \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates an expression that returns a result, and fatals the result if it would fail.
|
||||
#define R_ASSERT(res_expr) \
|
||||
({ \
|
||||
const auto _tmp_r_assert_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_assert_rc)) { \
|
||||
::sts::result::impl::OnResultAssertion(_tmp_r_assert_rc); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates a boolean expression, and returns a result unless that expression is true.
|
||||
#define R_UNLESS(expr, res) \
|
||||
({ \
|
||||
if (!(expr)) { \
|
||||
return static_cast<::sts::Result>(res); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Helpers for pattern-matching on a result expression, if the result would fail.
|
||||
#define R_CURRENT_RESULT _tmp_r_current_result
|
||||
|
||||
#define R_TRY_CATCH(res_expr) \
|
||||
({ \
|
||||
const auto R_CURRENT_RESULT = res_expr; \
|
||||
if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
if (false)
|
||||
|
||||
namespace sts::result::impl {
|
||||
|
||||
template<typename... Rs>
|
||||
NX_CONSTEXPR bool AnyIncludes(Result result) {
|
||||
return (Rs::Includes(result) || ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define R_CATCH(...) \
|
||||
} else if (::sts::result::impl::AnyIncludes<__VA_ARGS__>(R_CURRENT_RESULT)) { \
|
||||
if (true)
|
||||
|
||||
#define R_CONVERT(catch_type, convert_type) \
|
||||
R_CATCH(catch_type) { return static_cast<::sts::Result>(convert_type); }
|
||||
|
||||
#define R_CATCH_ALL() \
|
||||
} else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
if (true)
|
||||
|
||||
#define R_CONVERT_ALL(convert_type) \
|
||||
R_CATCH_ALL() { return static_cast<::sts::Result>(convert_type); }
|
||||
|
||||
#define R_END_TRY_CATCH \
|
||||
else if (R_FAILED(R_CURRENT_RESULT)) { \
|
||||
return R_CURRENT_RESULT; \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
#define R_END_TRY_CATCH_WITH_ASSERT \
|
||||
else { \
|
||||
R_ASSERT(R_CURRENT_RESULT); \
|
||||
} \
|
||||
} \
|
||||
})
|
@ -15,26 +15,31 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Ro = 22;
|
||||
namespace sts::ro {
|
||||
|
||||
static constexpr Result ResultRoInsufficientAddressSpace = MAKERESULT(Module_Ro, 2);
|
||||
static constexpr Result ResultRoAlreadyLoaded = MAKERESULT(Module_Ro, 3);
|
||||
static constexpr Result ResultRoInvalidNro = MAKERESULT(Module_Ro, 4);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(22);
|
||||
|
||||
static constexpr Result ResultRoInvalidNrr = MAKERESULT(Module_Ro, 6);
|
||||
static constexpr Result ResultRoTooManyNro = MAKERESULT(Module_Ro, 7);
|
||||
static constexpr Result ResultRoTooManyNrr = MAKERESULT(Module_Ro, 8);
|
||||
static constexpr Result ResultRoNotAuthorized = MAKERESULT(Module_Ro, 9);
|
||||
static constexpr Result ResultRoInvalidNrrType = MAKERESULT(Module_Ro, 10);
|
||||
R_DEFINE_ERROR_RANGE(RoError, 1, 1023);
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 2);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyLoaded, 3);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNro, 4);
|
||||
|
||||
static constexpr Result ResultRoInternalError = MAKERESULT(Module_Ro, 1023);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrr, 6);
|
||||
R_DEFINE_ERROR_RESULT(TooManyNro, 7);
|
||||
R_DEFINE_ERROR_RESULT(TooManyNrr, 8);
|
||||
R_DEFINE_ERROR_RESULT(NotAuthorized, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNrrType, 10);
|
||||
|
||||
static constexpr Result ResultRoInvalidAddress = MAKERESULT(Module_Ro, 1025);
|
||||
static constexpr Result ResultRoInvalidSize = MAKERESULT(Module_Ro, 1026);
|
||||
R_DEFINE_ERROR_RESULT(InternalError, 1023);
|
||||
|
||||
static constexpr Result ResultRoNotLoaded = MAKERESULT(Module_Ro, 1028);
|
||||
static constexpr Result ResultRoNotRegistered = MAKERESULT(Module_Ro, 1029);
|
||||
static constexpr Result ResultRoInvalidSession = MAKERESULT(Module_Ro, 1030);
|
||||
static constexpr Result ResultRoInvalidProcess = MAKERESULT(Module_Ro, 1031);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 1025);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 1026);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotLoaded, 1028);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 1029);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSession, 1030);
|
||||
R_DEFINE_ERROR_RESULT(InvalidProcess, 1031);
|
||||
|
||||
}
|
||||
|
@ -15,27 +15,33 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Settings = 105;
|
||||
namespace sts::settings {
|
||||
|
||||
static constexpr Result ResultSettingsItemNotFound = MAKERESULT(Module_Settings, 11);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(105);
|
||||
|
||||
static constexpr Result ResultSettingsItemKeyAllocationFailed = MAKERESULT(Module_Settings, 101);
|
||||
static constexpr Result ResultSettingsItemValueAllocationFailed = MAKERESULT(Module_Settings, 102);
|
||||
R_DEFINE_ERROR_RESULT(ItemNotFound, 11);
|
||||
|
||||
static constexpr Result ResultSettingsItemNameNull = MAKERESULT(Module_Settings, 201);
|
||||
static constexpr Result ResultSettingsItemKeyNull = MAKERESULT(Module_Settings, 202);
|
||||
static constexpr Result ResultSettingsItemValueNull = MAKERESULT(Module_Settings, 203);
|
||||
static constexpr Result ResultSettingsItemKeyBufferNull = MAKERESULT(Module_Settings, 204);
|
||||
static constexpr Result ResultSettingsItemValueBufferNull = MAKERESULT(Module_Settings, 205);
|
||||
R_DEFINE_ERROR_RANGE(InternalError, 100, 149);
|
||||
R_DEFINE_ERROR_RESULT(ItemKeyAllocationFailed, 101);
|
||||
R_DEFINE_ERROR_RESULT(ItemValueAllocationFailed, 102);
|
||||
|
||||
static constexpr Result ResultSettingsItemNameEmpty = MAKERESULT(Module_Settings, 221);
|
||||
static constexpr Result ResultSettingsItemKeyEmpty = MAKERESULT(Module_Settings, 222);
|
||||
R_DEFINE_ERROR_RANGE(InvalidArgument, 200, 399);
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameNull, 201);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyNull, 202);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueNull, 203);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyBufferNull, 204);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueBufferNull, 205);
|
||||
|
||||
static constexpr Result ResultSettingsItemNameTooLong = MAKERESULT(Module_Settings, 241);
|
||||
static constexpr Result ResultSettingsItemKeyTooLong = MAKERESULT(Module_Settings, 242);
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameEmpty, 221);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyEmpty, 222);
|
||||
|
||||
static constexpr Result ResultSettingsItemNameInvalidFormat = MAKERESULT(Module_Settings, 261);
|
||||
static constexpr Result ResultSettingsItemKeyInvalidFormat = MAKERESULT(Module_Settings, 262);
|
||||
static constexpr Result ResultSettingsItemValueInvalidFormat = MAKERESULT(Module_Settings, 263);
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameTooLong, 241);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyTooLong, 242);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(SettingsNameInvalidFormat, 261);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemKeyInvalidFormat, 262);
|
||||
R_DEFINE_ERROR_RESULT(SettingsItemValueInvalidFormat, 263);
|
||||
|
||||
}
|
||||
|
@ -15,25 +15,40 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_ServiceFramework = 10;
|
||||
namespace sts::sf {
|
||||
|
||||
static constexpr Result ResultServiceFrameworkNotSupported = MAKERESULT(Module_ServiceFramework, 1);
|
||||
static constexpr Result ResultServiceFrameworkPreconditionViolation = MAKERESULT(Module_ServiceFramework, 3);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(10);
|
||||
|
||||
static constexpr Result ResultServiceFrameworkInvalidCmifHeaderSize = MAKERESULT(Module_ServiceFramework, 202);
|
||||
static constexpr Result ResultServiceFrameworkInvalidCmifInHeader = MAKERESULT(Module_ServiceFramework, 211);
|
||||
static constexpr Result ResultServiceFrameworkUnknownCmifCommandId = MAKERESULT(Module_ServiceFramework, 221);
|
||||
static constexpr Result ResultServiceFrameworkInvalidCmifOutRawSize = MAKERESULT(Module_ServiceFramework, 232);
|
||||
static constexpr Result ResultServiceFrameworkInvalidCmifNumInObjects = MAKERESULT(Module_ServiceFramework, 235);
|
||||
static constexpr Result ResultServiceFrameworkInvalidCmifNumOutObjects = MAKERESULT(Module_ServiceFramework, 236);
|
||||
static constexpr Result ResultServiceFrameworkInvalidCmifInObject = MAKERESULT(Module_ServiceFramework, 239);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 1);
|
||||
R_DEFINE_ERROR_RESULT(PreconditionViolation, 3);
|
||||
|
||||
static constexpr Result ResultServiceFrameworkTargetNotFound = MAKERESULT(Module_ServiceFramework, 261);
|
||||
namespace cmif {
|
||||
|
||||
static constexpr Result ResultServiceFrameworkOutOfDomainEntries = MAKERESULT(Module_ServiceFramework, 301);
|
||||
R_DEFINE_ERROR_RESULT(InvalidHeaderSize, 202);
|
||||
R_DEFINE_ERROR_RESULT(InvalidInHeader, 211);
|
||||
R_DEFINE_ERROR_RESULT(UnknownCommandId, 221);
|
||||
R_DEFINE_ERROR_RESULT(InvalidOutRawSize, 232);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNumInObjects, 235);
|
||||
R_DEFINE_ERROR_RESULT(InvalidNumOutObjects, 236);
|
||||
R_DEFINE_ERROR_RESULT(InvalidInObject, 239);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(TargetNotFound, 261);
|
||||
|
||||
static constexpr Result ResultServiceFrameworkRequestDeferred = MAKERESULT(Module_ServiceFramework, 811);
|
||||
static constexpr Result ResultServiceFrameworkRequestDeferredByUser = MAKERESULT(Module_ServiceFramework, 812);
|
||||
R_DEFINE_ERROR_RESULT(OutOfDomainEntries, 301);
|
||||
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestContextChanged, 800, 899);
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestInvalidated, 801, 809);
|
||||
R_DEFINE_ERROR_RESULT(RequestInvalidatedByUser, 802);
|
||||
|
||||
}
|
||||
|
||||
R_DEFINE_ABSTRACT_ERROR_RANGE(RequestDeferred, 811, 819);
|
||||
R_DEFINE_ERROR_RESULT(RequestDeferredByUser, 812);
|
||||
|
||||
}
|
||||
|
@ -15,16 +15,20 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Sm = 21;
|
||||
namespace sts::sm {
|
||||
|
||||
static constexpr Result ResultSmInsufficientProcesses = MAKERESULT(Module_Sm, 1);
|
||||
static constexpr Result ResultSmInvalidClient = MAKERESULT(Module_Sm, 2);
|
||||
static constexpr Result ResultSmInsufficientSessions = MAKERESULT(Module_Sm, 3);
|
||||
static constexpr Result ResultSmAlreadyRegistered = MAKERESULT(Module_Sm, 4);
|
||||
static constexpr Result ResultSmInsufficientServices = MAKERESULT(Module_Sm, 5);
|
||||
static constexpr Result ResultSmInvalidServiceName = MAKERESULT(Module_Sm, 6);
|
||||
static constexpr Result ResultSmNotRegistered = MAKERESULT(Module_Sm, 7);
|
||||
static constexpr Result ResultSmNotAllowed = MAKERESULT(Module_Sm, 8);
|
||||
static constexpr Result ResultSmTooLargeAccessControl = MAKERESULT(Module_Sm, 9);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(21);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfProcesses, 1);
|
||||
R_DEFINE_ERROR_RESULT(InvalidClient, 2);
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessions, 3);
|
||||
R_DEFINE_ERROR_RESULT(AlreadyRegistered, 4);
|
||||
R_DEFINE_ERROR_RESULT(OutOfServices, 5);
|
||||
R_DEFINE_ERROR_RESULT(InvalidServiceName, 6);
|
||||
R_DEFINE_ERROR_RESULT(NotRegistered, 7);
|
||||
R_DEFINE_ERROR_RESULT(NotAllowed, 8);
|
||||
R_DEFINE_ERROR_RESULT(TooLargeAccessControl, 9);
|
||||
|
||||
}
|
||||
|
@ -15,25 +15,28 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Spl = 26;
|
||||
namespace sts::spl {
|
||||
|
||||
/* Results 1-99 are converted smc results. */
|
||||
static constexpr Result ResultSplSmcNotImplemented = MAKERESULT(Module_Spl, 1);
|
||||
static constexpr Result ResultSplSmcInvalidArgument = MAKERESULT(Module_Spl, 2);
|
||||
static constexpr Result ResultSplSmcInProgress = MAKERESULT(Module_Spl, 3);
|
||||
static constexpr Result ResultSplSmcNoAsyncOperation = MAKERESULT(Module_Spl, 4);
|
||||
static constexpr Result ResultSplSmcInvalidAsyncOperation = MAKERESULT(Module_Spl, 5);
|
||||
static constexpr Result ResultSplSmcBlacklisted = MAKERESULT(Module_Spl, 6);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(26);
|
||||
|
||||
/* Results 100+ are spl results. */
|
||||
static constexpr Result ResultSplInvalidSize = MAKERESULT(Module_Spl, 100);
|
||||
static constexpr Result ResultSplUnknownSmcResult = MAKERESULT(Module_Spl, 101);
|
||||
static constexpr Result ResultSplDecryptionFailed = MAKERESULT(Module_Spl, 102);
|
||||
R_DEFINE_ERROR_RANGE(SecureMonitorError, 0, 99);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotImplemented, 1);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidArgument, 2);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorBusy, 3);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNoAsyncOperation, 4);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorInvalidAsyncOperation, 5);
|
||||
R_DEFINE_ERROR_RESULT(SecureMonitorNotPermitted, 6);
|
||||
|
||||
static constexpr Result ResultSplOutOfKeyslots = MAKERESULT(Module_Spl, 104);
|
||||
static constexpr Result ResultSplInvalidKeyslot = MAKERESULT(Module_Spl, 105);
|
||||
static constexpr Result ResultSplBootReasonAlreadySet = MAKERESULT(Module_Spl, 106);
|
||||
static constexpr Result ResultSplBootReasonNotSet = MAKERESULT(Module_Spl, 107);
|
||||
static constexpr Result ResultSplInvalidArgument = MAKERESULT(Module_Spl, 108);
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 100);
|
||||
R_DEFINE_ERROR_RESULT(UnknownSecureMonitorError, 101);
|
||||
R_DEFINE_ERROR_RESULT(DecryptionFailed, 102);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfKeyslots, 104);
|
||||
R_DEFINE_ERROR_RESULT(InvalidKeyslot, 105);
|
||||
R_DEFINE_ERROR_RESULT(BootReasonAlreadySet, 106);
|
||||
R_DEFINE_ERROR_RESULT(BootReasonNotSet, 107);
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 108);
|
||||
|
||||
}
|
||||
|
73
include/stratosphere/results/svc_results.hpp
Normal file
73
include/stratosphere/results/svc_results.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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 "results_common.hpp"
|
||||
|
||||
namespace sts::svc {
|
||||
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(1);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OutOfSessions, 7);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 14);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NotImplemented, 33);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ThreadTerminating, 59);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(NoEvent, 70);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidSize, 101);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddress, 102);
|
||||
R_DEFINE_ERROR_RESULT(OutOfResource, 103);
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 104);
|
||||
R_DEFINE_ERROR_RESULT(OutOfHandles, 105);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCurrentMemoryState, 106);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidNewMemoryPermissions, 108);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidMemoryRegion, 110);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidPriority, 112);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCoreId, 113);
|
||||
R_DEFINE_ERROR_RESULT(InvalidHandle, 114);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPointer, 115);
|
||||
R_DEFINE_ERROR_RESULT(InvalidCombination, 116);
|
||||
R_DEFINE_ERROR_RESULT(TimedOut, 117);
|
||||
R_DEFINE_ERROR_RESULT(Cancelled, 118);
|
||||
R_DEFINE_ERROR_RESULT(OutOfRange, 119);
|
||||
R_DEFINE_ERROR_RESULT(InvalidEnumValue, 120);
|
||||
R_DEFINE_ERROR_RESULT(NotFound, 121);
|
||||
R_DEFINE_ERROR_RESULT(Busy, 122);
|
||||
R_DEFINE_ERROR_RESULT(SessionClosed, 123);
|
||||
R_DEFINE_ERROR_RESULT(NotHandled, 124);
|
||||
R_DEFINE_ERROR_RESULT(InvalidState, 125);
|
||||
R_DEFINE_ERROR_RESULT(ReservedValue, 126);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 127);
|
||||
R_DEFINE_ERROR_RESULT(Debug, 128);
|
||||
R_DEFINE_ERROR_RESULT(ThreadNotOwned, 129);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(PortClosed, 131);
|
||||
R_DEFINE_ERROR_RESULT(LimitReached, 132);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ReceiveListBroken, 258);
|
||||
R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 259);
|
||||
R_DEFINE_ERROR_RESULT(MessageTooLarge, 260);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(ProcessTerminated, 520);
|
||||
|
||||
}
|
@ -15,12 +15,16 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Updater = 158;
|
||||
namespace sts::updater {
|
||||
|
||||
static constexpr Result ResultUpdaterBootImagePackageNotFound = MAKERESULT(Module_Updater, 2);
|
||||
static constexpr Result ResultUpdaterInvalidBootImagePackage = MAKERESULT(Module_Updater, 3);
|
||||
static constexpr Result ResultUpdaterTooSmallWorkBuffer = MAKERESULT(Module_Updater, 4);
|
||||
static constexpr Result ResultUpdaterMisalignedWorkBuffer = MAKERESULT(Module_Updater, 5);
|
||||
static constexpr Result ResultUpdaterNeedsRepairBootImages = MAKERESULT(Module_Updater, 6);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(158);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(BootImagePackageNotFound, 2);
|
||||
R_DEFINE_ERROR_RESULT(InvalidBootImagePackage, 3);
|
||||
R_DEFINE_ERROR_RESULT(TooSmallWorkBuffer, 4);
|
||||
R_DEFINE_ERROR_RESULT(NotAlignedWorkBuffer, 5);
|
||||
R_DEFINE_ERROR_RESULT(NeedsRepairBootImages, 6);
|
||||
|
||||
}
|
||||
|
@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @file result_utilities.h
|
||||
* @brief Utilities for handling Results.
|
||||
* @author SciresM
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include <switch/result.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdlib>
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Evaluates an expression that returns a result, and returns the result if it would fail.
|
||||
#define R_TRY(res_expr) \
|
||||
({ \
|
||||
const Result _tmp_r_try_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_try_rc)) { \
|
||||
return _tmp_r_try_rc; \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Evaluates an expression that returns a result, and fatals the result if it would fail.
|
||||
#ifdef RESULT_ABORT_ON_ASSERT
|
||||
#define R_ASSERT_IMPL(res) std::abort()
|
||||
#else
|
||||
#define R_ASSERT_IMPL(res) fatalSimple(res)
|
||||
#endif
|
||||
|
||||
/// Evaluates a boolean expression, and returns a result unless that expression is true.
|
||||
#define R_UNLESS(expr, res) \
|
||||
({ \
|
||||
if (!(expr)) { \
|
||||
return static_cast<Result>(res); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define R_ASSERT(res_expr) \
|
||||
({ \
|
||||
const Result _tmp_r_assert_rc = res_expr; \
|
||||
if (R_FAILED(_tmp_r_assert_rc)) { \
|
||||
R_ASSERT_IMPL(_tmp_r_assert_rc); \
|
||||
} \
|
||||
})
|
||||
|
||||
/// Helpers for pattern-matching on a result expression, if the result would fail.
|
||||
#define R_TRY_CATCH_RESULT _tmp_r_try_catch_rc
|
||||
|
||||
#define R_TRY_CATCH(res_expr) \
|
||||
({ \
|
||||
const Result R_TRY_CATCH_RESULT = res_expr; \
|
||||
if (R_FAILED(R_TRY_CATCH_RESULT)) { \
|
||||
if (false)
|
||||
|
||||
#define R_CATCH(catch_result) \
|
||||
} else if (R_TRY_CATCH_RESULT == catch_result) { \
|
||||
_Static_assert(R_FAILED(catch_result), "Catch result must be constexpr error Result!"); \
|
||||
if (false) { } \
|
||||
else
|
||||
|
||||
#define R_GET_CATCH_RANGE_IMPL(_1, _2, NAME, ...) NAME
|
||||
|
||||
#define R_CATCH_RANGE_IMPL_2(catch_result_start, catch_result_end) \
|
||||
} else if (catch_result_start <= R_TRY_CATCH_RESULT && R_TRY_CATCH_RESULT <= catch_result_end) { \
|
||||
_Static_assert(R_FAILED(catch_result_start), "Catch start result must be constexpr error Result!"); \
|
||||
_Static_assert(R_FAILED(catch_result_end), "Catch end result must be constexpr error Result!"); \
|
||||
_Static_assert(R_MODULE(catch_result_start) == R_MODULE(catch_result_end), "Catch range modules must be equal!"); \
|
||||
if (false) { } \
|
||||
else
|
||||
|
||||
#define R_CATCH_RANGE_IMPL_1(catch_result) R_CATCH_RANGE_IMPL_2(catch_result##RangeStart, catch_result##RangeEnd)
|
||||
|
||||
#define R_CATCH_RANGE(...) R_GET_CATCH_RANGE_IMPL(__VA_ARGS__, R_CATCH_RANGE_IMPL_2, R_CATCH_RANGE_IMPL_1)(__VA_ARGS__)
|
||||
|
||||
#define R_CATCH_MODULE(module) \
|
||||
} else if (R_MODULE(R_TRY_CATCH_RESULT) == module) { \
|
||||
_Static_assert(module != 0, "Catch module must be error!"); \
|
||||
if (false) { } \
|
||||
else
|
||||
|
||||
#define R_CATCH_ALL() \
|
||||
} else if (R_FAILED(R_TRY_CATCH_RESULT)) { \
|
||||
if (false) { } \
|
||||
else
|
||||
|
||||
#define R_END_TRY_CATCH \
|
||||
else if (R_FAILED(R_TRY_CATCH_RESULT)) { \
|
||||
return R_TRY_CATCH_RESULT; \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
#define R_END_TRY_CATCH_WITH_ASSERT \
|
||||
else { \
|
||||
R_ASSERT(R_TRY_CATCH_RESULT); \
|
||||
} \
|
||||
} \
|
||||
})
|
||||
|
||||
|
||||
/// Evaluates an expression that returns a result, and returns the result (after evaluating a cleanup expression) if it would fail.
|
||||
#define R_CLEANUP_RESULT _tmp_r_try_cleanup_rc
|
||||
|
||||
#define R_TRY_CLEANUP(res_expr, cleanup_expr) \
|
||||
({ \
|
||||
const Result R_CLEANUP_RESULT = res_expr; \
|
||||
if (R_FAILED(R_CLEANUP_RESULT)) { \
|
||||
({ cleanup_expr }); \
|
||||
return R_CLEANUP_RESULT; \
|
||||
} \
|
||||
})
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// For C++, also define R_CATCH_MANY helper.
|
||||
#ifdef __cplusplus
|
||||
|
||||
template<Result... rs>
|
||||
constexpr inline bool _CheckResultsForMultiTryCatch(const Result &rc) {
|
||||
static_assert((R_FAILED(rs) && ...), "Multi try catch result must be constexpr error Result!");
|
||||
return ((rs == rc) || ...);
|
||||
}
|
||||
|
||||
#define R_CATCH_MANY(...) \
|
||||
} else if (_CheckResultsForMultiTryCatch<__VA_ARGS__>(_tmp_r_try_catch_rc)) { \
|
||||
if (false) { } \
|
||||
else
|
||||
|
||||
#endif
|
@ -15,10 +15,14 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "results_common.hpp"
|
||||
|
||||
static constexpr u32 Module_Vi = 114;
|
||||
namespace sts::vi {
|
||||
|
||||
static constexpr Result ResultViOperationFailed = MAKERESULT(Module_Vi, 1);
|
||||
static constexpr Result ResultViNotSupported = MAKERESULT(Module_Vi, 6);
|
||||
static constexpr Result ResultViNotFound = MAKERESULT(Module_Vi, 7);
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(114);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(OperationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NotSupported, 6);
|
||||
R_DEFINE_ERROR_RESULT(NotFound, 7);
|
||||
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ namespace sts::sf::hipc {
|
||||
static_holder = cmif::ServiceObjectHolder(std::move(static_object));
|
||||
}
|
||||
this->RegisterServerImpl<ServiceImpl, MakeShared>(port_handle, service_name, true, std::move(static_holder));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Processing. */
|
||||
|
@ -90,7 +90,7 @@ namespace sts::sf::hipc {
|
||||
Result CreateSessionImpl(ServerSession **out, const Constructor &ctor) {
|
||||
/* Allocate session. */
|
||||
ServerSession *session_memory = this->AllocateSession();
|
||||
R_UNLESS(session_memory != nullptr, ResultHipcSessionAllocationFailure);
|
||||
R_UNLESS(session_memory != nullptr, sf::hipc::ResultOutOfSessionMemory());
|
||||
/* Register session. */
|
||||
bool succeeded = false;
|
||||
ON_SCOPE_EXIT {
|
||||
@ -102,7 +102,7 @@ namespace sts::sf::hipc {
|
||||
/* Save new session to output. */
|
||||
succeeded = true;
|
||||
*out = session_memory;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
void DestroySession(ServerSession *session);
|
||||
|
||||
|
@ -52,14 +52,14 @@ namespace sts::sf {
|
||||
|
||||
constexpr inline Result MarshalProcessId(ClientProcessId &client, const os::ProcessId &client_process_id) {
|
||||
client.SetValue(client_process_id);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
constexpr inline Result MarshalProcessId(ClientAppletResourceUserId &client, const os::ProcessId &client_process_id) {
|
||||
if (client.GetValue() != client_process_id && client.GetValue() != os::ProcessId{}) {
|
||||
return ResultServiceFrameworkPreconditionViolation;
|
||||
return sf::ResultPreconditionViolation();
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
@ -167,6 +167,8 @@ namespace sts::sf::impl {
|
||||
return ArgumentType::OutData;
|
||||
} else if constexpr (std::is_trivial<T>::value && !std::is_pointer<T>::value) {
|
||||
return ArgumentType::InData;
|
||||
} else if constexpr (std::is_same<T, ::sts::Result>::value) {
|
||||
return ArgumentType::InData;
|
||||
} else {
|
||||
static_assert(!std::is_same<T, T>::value, "Invalid ArgumentType<T>");
|
||||
}
|
||||
@ -675,7 +677,7 @@ namespace sts::sf::impl {
|
||||
if constexpr (NumInObjects > 0) {
|
||||
R_TRY(processor->GetInObjects(this->in_object_holders.data()));
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<typename ServiceImplTuple>
|
||||
@ -685,7 +687,7 @@ namespace sts::sf::impl {
|
||||
if constexpr (NumInObjects > n) { \
|
||||
using SharedPtrToServiceImplType = typename std::tuple_element<n, ServiceImplTuple>::type; \
|
||||
using ServiceImplType = typename SharedPtrToServiceImplType::element_type; \
|
||||
R_UNLESS((this->in_object_holders[n].template IsServiceObjectValid<ServiceImplType>()), ResultServiceFrameworkInvalidCmifInObject); \
|
||||
R_UNLESS((this->in_object_holders[n].template IsServiceObjectValid<ServiceImplType>()), sf::cmif::ResultInvalidInObject()); \
|
||||
} \
|
||||
} while (0)
|
||||
_SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(0);
|
||||
@ -696,7 +698,8 @@ namespace sts::sf::impl {
|
||||
_SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(5);
|
||||
_SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(6);
|
||||
_SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(7);
|
||||
return ResultSuccess;
|
||||
#undef _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<size_t Index, typename ServiceImpl>
|
||||
@ -740,8 +743,8 @@ namespace sts::sf::impl {
|
||||
const size_t command_raw_size = util::AlignUp(runtime_metadata.GetUnfixedOutPointerSizeOffset() + (CommandMeta::NumUnfixedSizeOutHipcPointerBuffers * sizeof(u16)), alignof(u32));
|
||||
is_request_valid &= meta_raw_size >= command_raw_size;
|
||||
|
||||
R_UNLESS(is_request_valid, ResultHipcInvalidRequest);
|
||||
return ResultSuccess;
|
||||
R_UNLESS(is_request_valid, sf::hipc::ResultInvalidCmifRequest());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual HipcRequest PrepareForReply(const cmif::ServiceDispatchContext &ctx, cmif::PointerAndSize &out_raw_data, const cmif::ServerMessageRuntimeMetadata runtime_metadata) override final {
|
||||
@ -768,7 +771,7 @@ namespace sts::sf::impl {
|
||||
|
||||
virtual Result GetInObjects(cmif::ServiceObjectHolder *in_objects) const override final {
|
||||
/* By default, InObjects aren't supported. */
|
||||
return ResultServiceFrameworkNotSupported;
|
||||
return sf::ResultNotSupported();
|
||||
}
|
||||
|
||||
virtual void SetOutObjects(const cmif::ServiceDispatchContext &ctx, const HipcRequest &response, cmif::ServiceObjectHolder *out_objects, cmif::DomainObjectId *ids) override final {
|
||||
@ -949,11 +952,11 @@ namespace sts::sf::impl {
|
||||
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(6);
|
||||
_SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL(7);
|
||||
#undef _SF_IMPL_PROCESSOR_PROCESS_BUFFER_IMPL
|
||||
R_UNLESS(map_alias_buffers_valid, ResultHipcInvalidRequest);
|
||||
R_UNLESS(map_alias_buffers_valid, sf::hipc::ResultInvalidCmifRequest());
|
||||
if constexpr (CommandMeta::NumOutHipcPointerBuffers > 0) {
|
||||
R_UNLESS(pointer_buffer_tail <= pointer_buffer_head, ResultHipcPointerBufferTooSmall);
|
||||
R_UNLESS(pointer_buffer_tail <= pointer_buffer_head, sf::hipc::ResultPointerBufferTooSmall());
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
NX_CONSTEXPR void SetOutBuffers(const HipcRequest &response, const BufferArrayType &buffers, const std::array<bool, CommandMeta::NumBuffers> &is_buffer_map_alias) {
|
||||
@ -1045,10 +1048,10 @@ namespace sts::sf::impl {
|
||||
|
||||
constexpr Result GetCmifOutHeaderPointer(CmifOutHeader **out_header_ptr, cmif::PointerAndSize &out_raw_data) {
|
||||
CmifOutHeader *header = reinterpret_cast<CmifOutHeader *>(out_raw_data.GetPointer());
|
||||
R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(out_raw_data.GetSize() >= sizeof(*header), sf::cmif::ResultInvalidHeaderSize());
|
||||
out_raw_data = cmif::PointerAndSize(out_raw_data.GetAddress() + sizeof(*header), out_raw_data.GetSize() - sizeof(*header));
|
||||
*out_header_ptr = header;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
template<auto ServiceCommandImpl>
|
||||
@ -1101,11 +1104,13 @@ namespace sts::sf::impl {
|
||||
}
|
||||
|
||||
if constexpr (CommandMeta::ReturnsResult) {
|
||||
R_TRY_CLEANUP(std::apply([=](auto&&... args) { return (this_ptr->*ServiceCommandImpl)(args...); }, args_tuple), {
|
||||
const auto command_result = std::apply([=](auto&&... args) { return (this_ptr->*ServiceCommandImpl)(args...); }, args_tuple);
|
||||
if (R_FAILED(command_result)) {
|
||||
cmif::PointerAndSize out_raw_data;
|
||||
ctx.processor->PrepareForErrorReply(ctx, out_raw_data, runtime_metadata);
|
||||
R_TRY(GetCmifOutHeaderPointer(out_header_ptr, out_raw_data));
|
||||
});
|
||||
return command_result;
|
||||
}
|
||||
} else {
|
||||
std::apply([=](auto&&... args) { (this_ptr->*ServiceCommandImpl)(args...); }, args_tuple);
|
||||
}
|
||||
@ -1117,7 +1122,7 @@ namespace sts::sf::impl {
|
||||
R_TRY(GetCmifOutHeaderPointer(out_header_ptr, out_raw_data));
|
||||
|
||||
/* Copy raw data output struct. */
|
||||
R_UNLESS(out_raw_data.GetSize() >= OutRawHolderType::Size, ResultServiceFrameworkInvalidCmifOutRawSize);
|
||||
R_UNLESS(out_raw_data.GetSize() >= OutRawHolderType::Size, sf::cmif::ResultInvalidOutRawSize());
|
||||
out_raw_holder.CopyTo(out_raw_data.GetPointer());
|
||||
|
||||
/* Set output recvlist buffers. */
|
||||
@ -1129,7 +1134,7 @@ namespace sts::sf::impl {
|
||||
/* Set output objects. */
|
||||
in_out_objects_holder.SetOutObjects(ctx, response);
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ namespace sts::sf {
|
||||
template<typename>
|
||||
struct IsOutForceEnabled : public std::false_type{};
|
||||
|
||||
template<>
|
||||
struct IsOutForceEnabled<::sts::Result> : public std::true_type{};
|
||||
|
||||
template<typename T>
|
||||
using IsOutEnabled = typename std::enable_if<std::is_trivial<T>::value || IsOutForceEnabled<T>::value>::type;
|
||||
|
||||
|
@ -21,14 +21,14 @@
|
||||
namespace sts::sm {
|
||||
|
||||
/* Utility, for scoped access to libnx services. */
|
||||
template<Result Initializer(), void Finalizer()>
|
||||
template<auto Initializer(), void Finalizer()>
|
||||
class ScopedServiceHolder {
|
||||
NON_COPYABLE(ScopedServiceHolder);
|
||||
private:
|
||||
Result result;
|
||||
bool has_initialized;
|
||||
public:
|
||||
ScopedServiceHolder(bool initialize = true) : result(ResultSuccess), has_initialized(false) {
|
||||
ScopedServiceHolder(bool initialize = true) : result(ResultSuccess()), has_initialized(false) {
|
||||
if (initialize) {
|
||||
this->Initialize();
|
||||
}
|
||||
@ -43,7 +43,7 @@ namespace sts::sm {
|
||||
ScopedServiceHolder(ScopedServiceHolder&& rhs) {
|
||||
this->result = rhs.result;
|
||||
this->has_initialized = rhs.has_initialized;
|
||||
rhs.result = ResultSuccess;
|
||||
rhs.result = ResultSuccess();
|
||||
rhs.has_initialized = false;
|
||||
}
|
||||
|
||||
|
@ -61,19 +61,20 @@ namespace sts::spl {
|
||||
InProgress = 3,
|
||||
NoAsyncOperation = 4,
|
||||
InvalidAsyncOperation = 5,
|
||||
Blacklisted = 6,
|
||||
|
||||
Max = 99,
|
||||
NotPermitted = 6,
|
||||
};
|
||||
|
||||
inline ::Result ConvertResult(Result result) {
|
||||
if (result == Result::Success) {
|
||||
return ResultSuccess;
|
||||
constexpr inline ::sts::Result ConvertResult(Result smc_result) {
|
||||
/* smc::Result::Success becomes ResultSuccess() directly. */
|
||||
R_UNLESS(smc_result != Result::Success, ResultSuccess());
|
||||
|
||||
/* Convert to the list of known SecureMonitorErrors. */
|
||||
const auto converted = R_MAKE_NAMESPACE_RESULT(::sts::spl, static_cast<u32>(smc_result));
|
||||
if (spl::ResultSecureMonitorError::Includes(converted)) {
|
||||
return converted;
|
||||
}
|
||||
if (result < Result::Max) {
|
||||
return MAKERESULT(Module_Spl, static_cast<u32>(result));
|
||||
}
|
||||
return ResultSplUnknownSmcResult;
|
||||
|
||||
return spl::ResultUnknownSecureMonitorError();
|
||||
}
|
||||
|
||||
enum class CipherMode {
|
||||
|
@ -24,24 +24,54 @@ namespace sts::util {
|
||||
/* Utilities for alignment to power of two. */
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline T AlignUp(T value, size_t alignment) {
|
||||
constexpr inline T AlignUp(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return static_cast<T>((value + invmask) & ~invmask);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline T AlignDown(T value, size_t alignment) {
|
||||
constexpr inline T AlignDown(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return static_cast<T>(value & ~invmask);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr inline bool IsAligned(T value, size_t alignment) {
|
||||
constexpr inline bool IsAligned(T value, size_t alignment) {
|
||||
using U = typename std::make_unsigned<T>::type;
|
||||
const U invmask = static_cast<U>(alignment - 1);
|
||||
return (value & invmask) == 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline void *AlignUp<void *>(void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignUp(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline const void *AlignUp<const void *>(const void *value, size_t alignment) {
|
||||
return reinterpret_cast<const void *>(AlignUp(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline void *AlignDown<void *>(void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignDown(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline const void *AlignDown<const void *>(const void *value, size_t alignment) {
|
||||
return reinterpret_cast<void *>(AlignDown(reinterpret_cast<uintptr_t>(value), alignment));
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline bool IsAligned<void *>(void *value, size_t alignment) {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr inline bool IsAligned<const void *>(const void *value, size_t alignment) {
|
||||
return IsAligned(reinterpret_cast<uintptr_t>(value), alignment);
|
||||
}
|
||||
|
||||
}
|
@ -125,7 +125,7 @@ namespace sts::ams {
|
||||
::sts::ams::ExceptionHandler(&ams_ctx);
|
||||
}
|
||||
|
||||
inline __attribute((noreturn)) void AbortImpl() {
|
||||
inline NORETURN void AbortImpl() {
|
||||
/* Just perform a data abort. */
|
||||
register u64 addr __asm__("x27") = FatalErrorContext::StdAbortMagicAddress;
|
||||
register u64 val __asm__("x28") = FatalErrorContext::StdAbortMagicValue;
|
||||
@ -145,9 +145,24 @@ extern "C" {
|
||||
/* Redefine abort to trigger these handlers. */
|
||||
void abort();
|
||||
|
||||
/* Redefine C++ exception handlers. Requires wrap linker flag. */
|
||||
void __wrap___cxa_pure_virtual(void) { abort(); }
|
||||
void __wrap___cxa_throw(void) { abort(); }
|
||||
void __wrap___cxa_rethrow(void) { abort(); }
|
||||
void __wrap___cxa_allocate_exception(void) { abort(); }
|
||||
void __wrap___cxa_begin_catch(void) { abort(); }
|
||||
void __wrap___cxa_end_catch(void) { abort(); }
|
||||
void __wrap___cxa_call_unexpected(void) { abort(); }
|
||||
void __wrap___cxa_call_terminate(void) { abort(); }
|
||||
void __wrap___gxx_personality_v0(void) { abort(); }
|
||||
|
||||
}
|
||||
|
||||
/* Custom abort handler, so that std::abort will trigger these. */
|
||||
void abort() {
|
||||
sts::ams::AbortImpl();
|
||||
}
|
||||
|
||||
void *__cxa_allocate_ecxeption(size_t thrown_size) {
|
||||
abort();
|
||||
}
|
@ -23,7 +23,7 @@ namespace sts::ams {
|
||||
ApiInfo GetApiInfo() {
|
||||
u64 exosphere_cfg;
|
||||
if (spl::smc::GetConfig(&exosphere_cfg, 1, SplConfigItem_ExosphereApiVersion) != spl::smc::Result::Success) {
|
||||
R_ASSERT(ResultAtmosphereExosphereNotPresent);
|
||||
R_ASSERT(ResultExosphereNotPresent());
|
||||
}
|
||||
|
||||
return ApiInfo{
|
||||
@ -61,7 +61,7 @@ namespace sts::ams {
|
||||
u64 tmp;
|
||||
R_TRY(spl::smc::ConvertResult(spl::smc::GetConfig(&tmp, 1, SplConfigItem_ExosphereHasRcmBugPatch)));
|
||||
*out = (tmp != 0);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -142,17 +142,14 @@ namespace sts::boot2 {
|
||||
void LaunchTitle(os::ProcessId *out_process_id, const ncm::TitleLocation &loc, u32 launch_flags) {
|
||||
os::ProcessId process_id = os::InvalidProcessId;
|
||||
|
||||
switch (pm::shell::LaunchTitle(&process_id, loc, launch_flags)) {
|
||||
case ResultKernelResourceExhausted:
|
||||
case ResultKernelOutOfMemory:
|
||||
case ResultKernelLimitReached:
|
||||
STS_ASSERT(false);
|
||||
default:
|
||||
/* We don't care about other issues. */
|
||||
break;
|
||||
/* Launch, lightly validate result. */
|
||||
{
|
||||
const auto launch_result = pm::shell::LaunchTitle(&process_id, loc, launch_flags);
|
||||
STS_ASSERT(!(svc::ResultOutOfResource::Includes(launch_result)));
|
||||
STS_ASSERT(!(svc::ResultOutOfMemory::Includes(launch_result)));
|
||||
STS_ASSERT(!(svc::ResultLimitReached::Includes(launch_result)));
|
||||
}
|
||||
|
||||
|
||||
if (out_process_id) {
|
||||
*out_process_id = process_id;
|
||||
}
|
||||
|
@ -43,11 +43,11 @@ namespace sts::cfg {
|
||||
bool service_present = false;
|
||||
R_TRY(sm::HasService(&service_present, RequiredServicesForSdCardAccess[i]));
|
||||
if (!service_present) {
|
||||
return ResultFsSdCardNotPresent;
|
||||
return fs::ResultSdCardNotPresent();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void WaitSdCardServicesReadyImpl() {
|
||||
@ -60,7 +60,7 @@ namespace sts::cfg {
|
||||
R_TRY(CheckSdCardServicesReady());
|
||||
R_ASSERT(fsOpenSdCardFileSystem(&g_sd_card_filesystem));
|
||||
g_sd_card_initialized = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void InitializeSdCard() {
|
||||
|
@ -24,7 +24,7 @@ namespace sts::dd {
|
||||
const u64 aligned_size = size + offset;
|
||||
R_TRY_CATCH(svcQueryIoMapping(&virtual_addr, aligned_addr, aligned_size)) {
|
||||
/* Official software handles this by returning 0. */
|
||||
R_CATCH(ResultKernelNotFound) { return 0; }
|
||||
R_CATCH(svc::ResultNotFound) { return 0; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
return static_cast<uintptr_t>(virtual_addr + offset);
|
||||
|
@ -47,7 +47,7 @@ namespace sts::hid {
|
||||
g_initialized_hid = true;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
@ -64,7 +64,7 @@ namespace sts::hid {
|
||||
*out |= hidKeysHeld(static_cast<HidControllerID>(controller));
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ namespace sts::kvdb {
|
||||
|
||||
Result Validate() const {
|
||||
if (std::memcmp(this->magic, ArchiveHeaderMagic, sizeof(ArchiveHeaderMagic)) != 0) {
|
||||
return ResultKvdbInvalidKeyValue;
|
||||
return ResultInvalidKeyValue();
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
static ArchiveHeader Make(size_t entry_count) {
|
||||
@ -54,9 +54,9 @@ namespace sts::kvdb {
|
||||
|
||||
Result Validate() const {
|
||||
if (std::memcmp(this->magic, ArchiveEntryMagic, sizeof(ArchiveEntryMagic)) != 0) {
|
||||
return ResultKvdbInvalidKeyValue;
|
||||
return ResultInvalidKeyValue();
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
static ArchiveEntryHeader Make(size_t ksz, size_t vsz) {
|
||||
@ -75,17 +75,17 @@ namespace sts::kvdb {
|
||||
Result ArchiveReader::Peek(void *dst, size_t size) {
|
||||
/* Bounds check. */
|
||||
if (this->offset + size > this->buffer.GetSize() || this->offset + size <= this->offset) {
|
||||
return ResultKvdbInvalidKeyValue;
|
||||
return ResultInvalidKeyValue();
|
||||
}
|
||||
|
||||
std::memcpy(dst, this->buffer.Get() + this->offset, size);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ArchiveReader::Read(void *dst, size_t size) {
|
||||
R_TRY(this->Peek(dst, size));
|
||||
this->offset += size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ArchiveReader::ReadEntryCount(size_t *out) {
|
||||
@ -98,7 +98,7 @@ namespace sts::kvdb {
|
||||
R_TRY(header.Validate());
|
||||
|
||||
*out = header.entry_count;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ArchiveReader::GetEntrySize(size_t *out_key_size, size_t *out_value_size) {
|
||||
@ -112,7 +112,7 @@ namespace sts::kvdb {
|
||||
|
||||
*out_key_size = header.key_size;
|
||||
*out_value_size = header.value_size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ArchiveReader::ReadEntry(void *out_key, size_t key_size, void *out_value, size_t value_size) {
|
||||
@ -130,19 +130,19 @@ namespace sts::kvdb {
|
||||
|
||||
R_ASSERT(this->Read(out_key, key_size));
|
||||
R_ASSERT(this->Read(out_value, value_size));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Writer functionality. */
|
||||
Result ArchiveWriter::Write(const void *src, size_t size) {
|
||||
/* Bounds check. */
|
||||
if (this->offset + size > this->buffer.GetSize() || this->offset + size <= this->offset) {
|
||||
return ResultKvdbInvalidKeyValue;
|
||||
return ResultInvalidKeyValue();
|
||||
}
|
||||
|
||||
std::memcpy(this->buffer.Get() + this->offset, src, size);
|
||||
this->offset += size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void ArchiveWriter::WriteHeader(size_t entry_count) {
|
||||
|
@ -41,11 +41,11 @@ namespace sts::kvdb {
|
||||
if (this->backing_buffer != nullptr) {
|
||||
this->entries = static_cast<decltype(this->entries)>(this->Allocate(sizeof(*this->entries) * this->capacity));
|
||||
if (this->entries == nullptr) {
|
||||
return ResultKvdbBufferInsufficient;
|
||||
return ResultBufferInsufficient();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void FileKeyValueStore::Cache::Invalidate() {
|
||||
@ -159,13 +159,13 @@ namespace sts::kvdb {
|
||||
const size_t file_name_len = file_name.GetLength();
|
||||
const size_t key_name_len = file_name_len - FileExtensionLength;
|
||||
if (file_name_len < FileExtensionLength + 2 || !file_name.EndsWith(FileExtension) || key_name_len % 2 != 0) {
|
||||
return ResultKvdbInvalidKeyValue;
|
||||
return ResultInvalidKeyValue();
|
||||
}
|
||||
|
||||
/* Validate that we have space for the converted key. */
|
||||
const size_t key_size = key_name_len / 2;
|
||||
if (key_size > max_out_size) {
|
||||
return ResultKvdbBufferInsufficient;
|
||||
return ResultBufferInsufficient();
|
||||
}
|
||||
|
||||
/* Convert the hex key back. */
|
||||
@ -177,7 +177,7 @@ namespace sts::kvdb {
|
||||
}
|
||||
|
||||
*out_size = key_size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileKeyValueStore::Initialize(const char *dir) {
|
||||
@ -189,7 +189,7 @@ namespace sts::kvdb {
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(dir, &st) != 0 || !(S_ISDIR(st.st_mode))) {
|
||||
return ResultFsPathNotFound;
|
||||
return fs::ResultPathNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Initialize our cache. */
|
||||
R_TRY(this->cache.Initialize(cache_buffer, cache_buffer_size, cache_capacity));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileKeyValueStore::Get(size_t *out_size, void *out_value, size_t max_out_size, const void *key, size_t key_size) {
|
||||
@ -206,7 +206,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Ensure key size is small enough. */
|
||||
if (key_size > MaxKeySize) {
|
||||
return ResultKvdbKeyCapacityInsufficient;
|
||||
return ResultKeyCapacityInsufficient();
|
||||
}
|
||||
|
||||
/* Try to get from cache. */
|
||||
@ -214,7 +214,7 @@ namespace sts::kvdb {
|
||||
auto size = this->cache.TryGet(out_value, max_out_size, key, key_size);
|
||||
if (size) {
|
||||
*out_size = *size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,9 +222,7 @@ namespace sts::kvdb {
|
||||
FILE *fp = fopen(this->GetPath(key, key_size), "rb");
|
||||
if (fp == nullptr) {
|
||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||
R_CATCH(ResultFsPathNotFound) {
|
||||
return ResultKvdbKeyNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
ON_SCOPE_EXIT { fclose(fp); };
|
||||
@ -236,7 +234,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Ensure there's enough space for the value. */
|
||||
if (max_out_size < value_size) {
|
||||
return ResultKvdbBufferInsufficient;
|
||||
return ResultBufferInsufficient();
|
||||
}
|
||||
|
||||
/* Read the value. */
|
||||
@ -247,7 +245,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Cache the newly read value. */
|
||||
this->cache.Set(key, key_size, out_value, value_size);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileKeyValueStore::GetSize(size_t *out_size, const void *key, size_t key_size) {
|
||||
@ -255,7 +253,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Ensure key size is small enough. */
|
||||
if (key_size > MaxKeySize) {
|
||||
return ResultKvdbKeyCapacityInsufficient;
|
||||
return ResultKeyCapacityInsufficient();
|
||||
}
|
||||
|
||||
/* Try to get from cache. */
|
||||
@ -263,7 +261,7 @@ namespace sts::kvdb {
|
||||
auto size = this->cache.TryGetSize(key, key_size);
|
||||
if (size) {
|
||||
*out_size = *size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,9 +269,7 @@ namespace sts::kvdb {
|
||||
FILE *fp = fopen(this->GetPath(key, key_size), "rb");
|
||||
if (fp == nullptr) {
|
||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||
R_CATCH(ResultFsPathNotFound) {
|
||||
return ResultKvdbKeyNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
ON_SCOPE_EXIT { fclose(fp); };
|
||||
@ -281,7 +277,7 @@ namespace sts::kvdb {
|
||||
/* Get the value size. */
|
||||
fseek(fp, 0, SEEK_END);
|
||||
*out_size = ftell(fp);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileKeyValueStore::Set(const void *key, size_t key_size, const void *value, size_t value_size) {
|
||||
@ -289,7 +285,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Ensure key size is small enough. */
|
||||
if (key_size > MaxKeySize) {
|
||||
return ResultKvdbKeyCapacityInsufficient;
|
||||
return ResultKeyCapacityInsufficient();
|
||||
}
|
||||
|
||||
/* When the cache contains the key being set, Nintendo invalidates the cache. */
|
||||
@ -316,7 +312,7 @@ namespace sts::kvdb {
|
||||
/* Flush the value file. */
|
||||
fflush(fp);
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FileKeyValueStore::Remove(const void *key, size_t key_size) {
|
||||
@ -324,7 +320,7 @@ namespace sts::kvdb {
|
||||
|
||||
/* Ensure key size is small enough. */
|
||||
if (key_size > MaxKeySize) {
|
||||
return ResultKvdbKeyCapacityInsufficient;
|
||||
return ResultKeyCapacityInsufficient();
|
||||
}
|
||||
|
||||
/* When the cache contains the key being set, Nintendo invalidates the cache. */
|
||||
@ -335,13 +331,11 @@ namespace sts::kvdb {
|
||||
/* Remove the file. */
|
||||
if (std::remove(this->GetPath(key, key_size)) != 0) {
|
||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||
R_CATCH(ResultFsPathNotFound) {
|
||||
return ResultKvdbKeyNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
@ -41,12 +41,12 @@ namespace sts::map {
|
||||
|
||||
if (mem_info.type == MemType_Unmapped && mem_info.addr - cur_base + mem_info.size >= size) {
|
||||
*out_address = cur_base;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
const uintptr_t mem_end = mem_info.addr + mem_info.size;
|
||||
if (mem_info.type == MemType_Reserved || mem_end < cur_base || (mem_end >> 31)) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
|
||||
cur_base = mem_end;
|
||||
@ -64,39 +64,39 @@ namespace sts::map {
|
||||
cur_end = cur_base + size;
|
||||
|
||||
if (cur_end <= cur_base) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (address_space.heap_size && (address_space.heap_base <= cur_end - 1 && cur_base <= address_space.heap_end - 1)) {
|
||||
/* If we overlap the heap region, go to the end of the heap region. */
|
||||
if (cur_base == address_space.heap_end) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
cur_base = address_space.heap_end;
|
||||
} else if (address_space.alias_size && (address_space.alias_base <= cur_end - 1 && cur_base <= address_space.alias_end - 1)) {
|
||||
/* If we overlap the alias region, go to the end of the alias region. */
|
||||
if (cur_base == address_space.alias_end) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
cur_base = address_space.alias_end;
|
||||
} else {
|
||||
R_ASSERT(svcQueryMemory(&mem_info, &page_info, cur_base));
|
||||
if (mem_info.type == 0 && mem_info.addr - cur_base + mem_info.size >= size) {
|
||||
*out_address = cur_base;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
if (mem_info.addr + mem_info.size <= cur_base) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
cur_base = mem_info.addr + mem_info.size;
|
||||
if (cur_base >= address_space.aslr_end) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
}
|
||||
cur_end = cur_base + size;
|
||||
if (cur_base + size <= cur_base) {
|
||||
return ResultKernelOutOfMemory;
|
||||
return svc::ResultOutOfMemory();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ namespace sts::map {
|
||||
R_TRY(GetProcessAddressSpaceInfo(&address_space, process_handle));
|
||||
|
||||
if (size > address_space.aslr_size) {
|
||||
return ResultRoInsufficientAddressSpace;
|
||||
return ro::ResultInsufficientAddressSpace();
|
||||
}
|
||||
|
||||
uintptr_t try_address;
|
||||
@ -115,7 +115,7 @@ namespace sts::map {
|
||||
|
||||
MappedCodeMemory tmp_mcm(process_handle, try_address, base_address, size);
|
||||
R_TRY_CATCH(tmp_mcm.GetResult()) {
|
||||
R_CATCH(ResultKernelInvalidMemoryState) {
|
||||
R_CATCH(svc::ResultInvalidCurrentMemoryState) {
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
@ -126,10 +126,10 @@ namespace sts::map {
|
||||
|
||||
/* We're done searching. */
|
||||
out_mcm = std::move(tmp_mcm);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
return ResultRoInsufficientAddressSpace;
|
||||
return ro::ResultInsufficientAddressSpace();;
|
||||
}
|
||||
|
||||
Result MapCodeMemoryInProcessModern(MappedCodeMemory &out_mcm, Handle process_handle, uintptr_t base_address, size_t size) {
|
||||
@ -137,7 +137,7 @@ namespace sts::map {
|
||||
R_TRY(GetProcessAddressSpaceInfo(&address_space, process_handle));
|
||||
|
||||
if (size > address_space.aslr_size) {
|
||||
return ResultRoInsufficientAddressSpace;
|
||||
return ro::ResultInsufficientAddressSpace();;
|
||||
}
|
||||
|
||||
uintptr_t try_address;
|
||||
@ -155,7 +155,7 @@ namespace sts::map {
|
||||
|
||||
MappedCodeMemory tmp_mcm(process_handle, try_address, base_address, size);
|
||||
R_TRY_CATCH(tmp_mcm.GetResult()) {
|
||||
R_CATCH(ResultKernelInvalidMemoryState) {
|
||||
R_CATCH(svc::ResultInvalidCurrentMemoryState) {
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
@ -166,10 +166,10 @@ namespace sts::map {
|
||||
|
||||
/* We're done searching. */
|
||||
out_mcm = std::move(tmp_mcm);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
return ResultRoInsufficientAddressSpace;
|
||||
return ro::ResultInsufficientAddressSpace();;
|
||||
}
|
||||
|
||||
}
|
||||
@ -201,7 +201,7 @@ namespace sts::map {
|
||||
out->heap_end = out->heap_base + out->heap_size;
|
||||
out->alias_end = out->alias_base + out->alias_size;
|
||||
out->aslr_end = out->aslr_base + out->aslr_size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LocateMappableSpace(uintptr_t *out_address, size_t size) {
|
||||
|
@ -23,12 +23,10 @@ namespace sts::os::impl {
|
||||
Result CreateEventHandles(Handle *out_readable, Handle *out_writable) {
|
||||
/* Create the event handles. */
|
||||
R_TRY_CATCH(svcCreateEvent(out_writable, out_readable)) {
|
||||
R_CATCH(ResultKernelResourceExhausted) {
|
||||
return ResultOsResourceExhausted;
|
||||
}
|
||||
R_CONVERT(svc::ResultOutOfResource, ResultOutOfResource());
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
@ -46,7 +44,7 @@ namespace sts::os::impl {
|
||||
Handle rh, wh;
|
||||
R_TRY(CreateEventHandles(&rh, &wh));
|
||||
this->Initialize(rh, true, wh, true, autoclear);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void InterProcessEvent::Initialize(Handle read_handle, bool manage_read_handle, Handle write_handle, bool manage_write_handle, bool autoclear) {
|
||||
@ -122,14 +120,14 @@ namespace sts::os::impl {
|
||||
while (true) {
|
||||
/* Continuously wait, until success. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(handle, U64_MAX)) {
|
||||
R_CATCH(ResultKernelCancelled) { continue; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* Clear, if we must. */
|
||||
if (this->auto_clear) {
|
||||
R_TRY_CATCH(svcResetSignal(handle)) {
|
||||
/* Some other thread might have caught this before we did. */
|
||||
R_CATCH(ResultKernelInvalidState) { continue; }
|
||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
}
|
||||
return;
|
||||
@ -147,8 +145,8 @@ namespace sts::os::impl {
|
||||
while (true) {
|
||||
/* Continuously wait, until success or timeout. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(handle, 0)) {
|
||||
R_CATCH(ResultKernelTimedOut) { return false; }
|
||||
R_CATCH(ResultKernelCancelled) { continue; }
|
||||
R_CATCH(svc::ResultTimedOut) { return false; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* We succeeded, so we're signaled. */
|
||||
@ -164,15 +162,15 @@ namespace sts::os::impl {
|
||||
while (true) {
|
||||
/* Continuously wait, until success or timeout. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(handle, timeout_helper.NsUntilTimeout())) {
|
||||
R_CATCH(ResultKernelTimedOut) { return false; }
|
||||
R_CATCH(ResultKernelCancelled) { continue; }
|
||||
R_CATCH(svc::ResultTimedOut) { return false; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* Clear, if we must. */
|
||||
if (this->auto_clear) {
|
||||
R_TRY_CATCH(svcResetSignal(handle)) {
|
||||
/* Some other thread might have caught this before we did. */
|
||||
R_CATCH(ResultKernelInvalidState) { continue; }
|
||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
}
|
||||
|
||||
|
@ -98,13 +98,13 @@ namespace sts::os::impl{
|
||||
s32 index = WaitInvalid;
|
||||
|
||||
R_TRY_CATCH(svcWaitSynchronization(&index, handles, count, timeout)) {
|
||||
R_CATCH(ResultKernelTimedOut) { return WaitTimedOut; }
|
||||
R_CATCH(ResultKernelCancelled) { return WaitCancelled; }
|
||||
R_CATCH(svc::ResultTimedOut) { return WaitTimedOut; }
|
||||
R_CATCH(svc::ResultCancelled) { return WaitCancelled; }
|
||||
/* All other results are critical errors. */
|
||||
/* 7601: Thread termination requested. */
|
||||
/* E401: Handle is dead. */
|
||||
/* E601: Handle list address invalid. */
|
||||
/* EE01: Too many handles. */
|
||||
/* svc::ResultThreadTerminating */
|
||||
/* svc::ResultInvalidHandle. */
|
||||
/* svc::ResultInvalidPointer */
|
||||
/* svc::ResultOutOfRange */
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
return index;
|
||||
|
@ -26,7 +26,7 @@ namespace sts::os {
|
||||
R_TRY(svcCreateInterruptEvent(this->handle.GetPointer(), interrupt_id, type));
|
||||
|
||||
this->is_initialized = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void InterruptEvent::Finalize() {
|
||||
@ -51,14 +51,14 @@ namespace sts::os {
|
||||
while (true) {
|
||||
/* Continuously wait, until success. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), U64_MAX)) {
|
||||
R_CATCH(ResultKernelCancelled) { continue; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* Clear, if we must. */
|
||||
if (this->auto_clear) {
|
||||
R_TRY_CATCH(svcResetSignal(this->handle.Get())) {
|
||||
/* Some other thread might have caught this before we did. */
|
||||
R_CATCH(ResultKernelInvalidState) { continue; }
|
||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
}
|
||||
return;
|
||||
@ -76,8 +76,8 @@ namespace sts::os {
|
||||
while (true) {
|
||||
/* Continuously wait, until success or timeout. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), 0)) {
|
||||
R_CATCH(ResultKernelTimedOut) { return false; }
|
||||
R_CATCH(ResultKernelCancelled) { continue; }
|
||||
R_CATCH(svc::ResultTimedOut) { return false; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* We succeeded, so we're signaled. */
|
||||
@ -93,15 +93,15 @@ namespace sts::os {
|
||||
while (true) {
|
||||
/* Continuously wait, until success or timeout. */
|
||||
R_TRY_CATCH(svcWaitSynchronizationSingle(this->handle.Get(), timeout_helper.NsUntilTimeout())) {
|
||||
R_CATCH(ResultKernelTimedOut) { return false; }
|
||||
R_CATCH(ResultKernelCancelled) { continue; }
|
||||
R_CATCH(svc::ResultTimedOut) { return false; }
|
||||
R_CATCH(svc::ResultCancelled) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* Clear, if we must. */
|
||||
if (this->auto_clear) {
|
||||
R_TRY_CATCH(svcResetSignal(this->handle.Get())) {
|
||||
/* Some other thread might have caught this before we did. */
|
||||
R_CATCH(ResultKernelInvalidState) { continue; }
|
||||
R_CATCH(svc::ResultInvalidState) { continue; }
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
}
|
||||
|
||||
|
@ -58,17 +58,22 @@ namespace sts::os {
|
||||
STS_ASSERT(this->state == SystemEventState::Uninitialized);
|
||||
new (GetPointer(this->storage_for_event)) Event(autoclear);
|
||||
this->state = SystemEventState::Event;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SystemEvent::InitializeAsInterProcessEvent(bool autoclear) {
|
||||
STS_ASSERT(this->state == SystemEventState::Uninitialized);
|
||||
new (GetPointer(this->storage_for_inter_process_event)) impl::InterProcessEvent();
|
||||
this->state = SystemEventState::InterProcessEvent;
|
||||
R_TRY_CLEANUP(this->GetInterProcessEvent().Initialize(autoclear), {
|
||||
this->Finalize();
|
||||
});
|
||||
return ResultSuccess;
|
||||
|
||||
/* Ensure we end up in a correct state if initialization fails. */
|
||||
{
|
||||
auto guard = SCOPE_GUARD { this->Finalize(); };
|
||||
R_TRY(this->GetInterProcessEvent().Initialize(autoclear));
|
||||
guard.Cancel();
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void SystemEvent::AttachHandles(Handle read_handle, bool manage_read_handle, Handle write_handle, bool manage_write_handle, bool autoclear) {
|
||||
|
@ -39,7 +39,7 @@ namespace sts::pm::dmnt {
|
||||
Event evt;
|
||||
R_TRY(pmdmntEnableDebugForApplication(&evt));
|
||||
*out_handle = evt.revent;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result AtmosphereGetProcessInfo(Handle *out_handle, ncm::TitleLocation *out_loc, os::ProcessId process_id) {
|
||||
|
@ -48,7 +48,7 @@ namespace sts::pm::info {
|
||||
|
||||
if (g_cached_launched_titles.find(static_cast<u64>(title_id)) != g_cached_launched_titles.end()) {
|
||||
*out = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
bool has_launched = false;
|
||||
@ -58,7 +58,7 @@ namespace sts::pm::info {
|
||||
}
|
||||
|
||||
*out = has_launched;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
bool HasLaunchedTitle(ncm::TitleId title_id) {
|
||||
|
38
source/result/result_on_assertion.cpp
Normal file
38
source/result/result_on_assertion.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 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/>.
|
||||
*/
|
||||
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace sts::result {
|
||||
|
||||
extern bool CallFatalOnResultAssertion;
|
||||
|
||||
}
|
||||
|
||||
namespace sts::result::impl {
|
||||
|
||||
NORETURN WEAK void OnResultAssertion(Result result) {
|
||||
/* Assert that we should call fatal on result assertion. */
|
||||
/* If we shouldn't fatal, this will std::abort(); */
|
||||
/* If we should, we'll continue onwards. */
|
||||
STS_ASSERT((sts::result::CallFatalOnResultAssertion));
|
||||
|
||||
/* TODO: sts::fatal:: */
|
||||
fatalSimple(result.GetValue());
|
||||
while (true) { /* ... */ }
|
||||
}
|
||||
|
||||
}
|
@ -34,11 +34,11 @@ namespace sts::sf::cmif {
|
||||
Result ServerDomainManager::Domain::ReserveIds(DomainObjectId *out_ids, size_t count) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
Entry *entry = this->manager->entry_manager.AllocateEntry();
|
||||
R_UNLESS(entry != nullptr, ResultServiceFrameworkOutOfDomainEntries);
|
||||
R_UNLESS(entry != nullptr, sf::cmif::ResultOutOfDomainEntries());
|
||||
STS_ASSERT(entry->owner == nullptr);
|
||||
out_ids[i] = this->manager->entry_manager.GetId(entry);
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void ServerDomainManager::Domain::ReserveSpecificIds(const DomainObjectId *ids, size_t count) {
|
||||
|
@ -28,7 +28,7 @@ namespace sts::sf::cmif {
|
||||
|
||||
Result DomainServiceObjectDispatchTable::ProcessMessageImpl(ServiceDispatchContext &ctx, ServerDomainBase *domain, const cmif::PointerAndSize &in_raw_data) const {
|
||||
const CmifDomainInHeader *in_header = reinterpret_cast<const CmifDomainInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
const cmif::PointerAndSize in_domain_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header));
|
||||
|
||||
const DomainObjectId target_object_id = DomainObjectId{in_header->object_id};
|
||||
@ -36,11 +36,11 @@ namespace sts::sf::cmif {
|
||||
case CmifDomainRequestType_SendMessage:
|
||||
{
|
||||
auto target_object = domain->GetObject(target_object_id);
|
||||
R_UNLESS(static_cast<bool>(target_object), ResultServiceFrameworkTargetNotFound);
|
||||
R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(static_cast<bool>(target_object), sf::cmif::ResultTargetNotFound());
|
||||
R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), sf::cmif::ResultInvalidHeaderSize());
|
||||
const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_domain_raw_data.GetAddress(), in_header->data_size);
|
||||
DomainObjectId in_object_ids[8];
|
||||
R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), ResultServiceFrameworkInvalidCmifNumInObjects);
|
||||
R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), sf::cmif::ResultInvalidNumInObjects());
|
||||
std::memcpy(in_object_ids, reinterpret_cast<DomainObjectId *>(in_message_raw_data.GetAddress() + in_message_raw_data.GetSize()), sizeof(DomainObjectId) * in_header->num_in_objects);
|
||||
DomainServiceObjectProcessor domain_processor(domain, in_object_ids, in_header->num_in_objects);
|
||||
if (ctx.processor == nullptr) {
|
||||
@ -54,15 +54,15 @@ namespace sts::sf::cmif {
|
||||
case CmifDomainRequestType_Close:
|
||||
/* TODO: N doesn't error check here. Should we? */
|
||||
domain->UnregisterObject(target_object_id);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
default:
|
||||
return ResultServiceFrameworkInvalidCmifInHeader;
|
||||
return sf::cmif::ResultInvalidInHeader();
|
||||
}
|
||||
}
|
||||
|
||||
Result DomainServiceObjectDispatchTable::ProcessMessageForMitmImpl(ServiceDispatchContext &ctx, ServerDomainBase *domain, const cmif::PointerAndSize &in_raw_data) const {
|
||||
const CmifDomainInHeader *in_header = reinterpret_cast<const CmifDomainInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
const cmif::PointerAndSize in_domain_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header));
|
||||
|
||||
const DomainObjectId target_object_id = DomainObjectId{in_header->object_id};
|
||||
@ -76,10 +76,10 @@ namespace sts::sf::cmif {
|
||||
return ctx.session->ForwardRequest(ctx);
|
||||
}
|
||||
|
||||
R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(in_header->data_size + in_header->num_in_objects * sizeof(DomainObjectId) <= in_domain_raw_data.GetSize(), sf::cmif::ResultInvalidHeaderSize());
|
||||
const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_domain_raw_data.GetAddress(), in_header->data_size);
|
||||
DomainObjectId in_object_ids[8];
|
||||
R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), ResultServiceFrameworkInvalidCmifNumInObjects);
|
||||
R_UNLESS(in_header->num_in_objects <= util::size(in_object_ids), sf::cmif::ResultInvalidNumInObjects());
|
||||
std::memcpy(in_object_ids, reinterpret_cast<DomainObjectId *>(in_message_raw_data.GetAddress() + in_message_raw_data.GetSize()), sizeof(DomainObjectId) * in_header->num_in_objects);
|
||||
DomainServiceObjectProcessor domain_processor(domain, in_object_ids, in_header->num_in_objects);
|
||||
if (ctx.processor == nullptr) {
|
||||
@ -101,16 +101,16 @@ namespace sts::sf::cmif {
|
||||
|
||||
/* If the object is in the domain, close our copy of it. Mitm objects are required to close their associated domain id, so this shouldn't cause desynch. */
|
||||
domain->UnregisterObject(target_object_id);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
default:
|
||||
return ResultServiceFrameworkInvalidCmifInHeader;
|
||||
return sf::cmif::ResultInvalidInHeader();
|
||||
}
|
||||
}
|
||||
|
||||
Result DomainServiceObjectProcessor::PrepareForProcess(const ServiceDispatchContext &ctx, const ServerMessageRuntimeMetadata runtime_metadata) const {
|
||||
/* Validate in object count. */
|
||||
R_UNLESS(this->impl_metadata.GetInObjectCount() == this->GetInObjectCount(), ResultServiceFrameworkInvalidCmifNumInObjects);
|
||||
R_UNLESS(this->impl_metadata.GetInObjectCount() == this->GetInObjectCount(), sf::cmif::ResultInvalidNumInObjects());
|
||||
|
||||
/* Nintendo reserves domain object IDs here. We do this later, to support mitm semantics. */
|
||||
|
||||
@ -122,7 +122,7 @@ namespace sts::sf::cmif {
|
||||
for (size_t i = 0; i < this->GetInObjectCount(); i++) {
|
||||
in_objects[i] = this->domain->GetObject(this->in_object_ids[i]);
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
HipcRequest DomainServiceObjectProcessor::PrepareForReply(const cmif::ServiceDispatchContext &ctx, PointerAndSize &out_raw_data, const ServerMessageRuntimeMetadata runtime_metadata) {
|
||||
|
@ -24,8 +24,8 @@ namespace sts::sf::cmif {
|
||||
|
||||
/* Parse the CMIF in header. */
|
||||
const CmifInHeader *in_header = reinterpret_cast<const CmifInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, ResultServiceFrameworkInvalidCmifInHeader);
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader());
|
||||
const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header));
|
||||
const u32 cmd_id = in_header->command_id;
|
||||
|
||||
@ -37,7 +37,7 @@ namespace sts::sf::cmif {
|
||||
break;
|
||||
}
|
||||
}
|
||||
R_UNLESS(cmd_handler != nullptr, ResultServiceFrameworkUnknownCmifCommandId);
|
||||
R_UNLESS(cmd_handler != nullptr, sf::cmif::ResultUnknownCommandId());
|
||||
|
||||
/* Invoke handler. */
|
||||
CmifOutHeader *out_header = nullptr;
|
||||
@ -45,16 +45,16 @@ namespace sts::sf::cmif {
|
||||
|
||||
/* Forward forwardable results, otherwise ensure we can send result to user. */
|
||||
R_TRY_CATCH(command_result) {
|
||||
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { return ResultServiceFrameworkRequestDeferredByUser; }
|
||||
R_CATCH(sf::impl::ResultRequestContextChanged) { return R_CURRENT_RESULT; }
|
||||
R_CATCH_ALL() { STS_ASSERT(out_header != nullptr); }
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* Write output header to raw data. */
|
||||
if (out_header != nullptr) {
|
||||
*out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result, 0};
|
||||
*out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result.GetValue(), 0};
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result impl::ServiceDispatchTableBase::ProcessMessageForMitmImpl(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const ServiceCommandMeta *entries, const size_t entry_count) const {
|
||||
@ -64,8 +64,8 @@ namespace sts::sf::cmif {
|
||||
|
||||
/* Parse the CMIF in header. */
|
||||
const CmifInHeader *in_header = reinterpret_cast<const CmifInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), ResultServiceFrameworkInvalidCmifHeaderSize);
|
||||
R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, ResultServiceFrameworkInvalidCmifInHeader);
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader());
|
||||
const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header));
|
||||
const u32 cmd_id = in_header->command_id;
|
||||
|
||||
@ -89,19 +89,19 @@ namespace sts::sf::cmif {
|
||||
|
||||
/* Forward forwardable results, otherwise ensure we can send result to user. */
|
||||
R_TRY_CATCH(command_result) {
|
||||
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { return ResultServiceFrameworkRequestDeferredByUser; }
|
||||
R_CATCH(ResultAtmosphereMitmShouldForwardToSession) {
|
||||
R_CATCH(ams::mitm::ResultShouldForwardToSession) {
|
||||
return ctx.session->ForwardRequest(ctx);
|
||||
}
|
||||
R_CATCH(sf::impl::ResultRequestContextChanged) { return R_CURRENT_RESULT; }
|
||||
R_CATCH_ALL() { STS_ASSERT(out_header != nullptr); }
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* Write output header to raw data. */
|
||||
if (out_header != nullptr) {
|
||||
*out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result, 0};
|
||||
*out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result.GetValue(), 0};
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,34 +43,34 @@ namespace sts::sf::hipc {
|
||||
|
||||
Result Receive(ReceiveResult *out_recv_result, Handle session_handle, const cmif::PointerAndSize &message_buffer) {
|
||||
R_TRY_CATCH(ReceiveImpl(session_handle, message_buffer.GetPointer(), message_buffer.GetSize())) {
|
||||
R_CATCH(ResultKernelConnectionClosed) {
|
||||
R_CATCH(svc::ResultSessionClosed) {
|
||||
*out_recv_result = ReceiveResult::Closed;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
R_CATCH(ResultKernelReceiveListBroken) {
|
||||
R_CATCH(svc::ResultReceiveListBroken) {
|
||||
*out_recv_result = ReceiveResult::NeedsRetry;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
*out_recv_result = ReceiveResult::Success;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Receive(bool *out_closed, Handle session_handle, const cmif::PointerAndSize &message_buffer) {
|
||||
R_TRY_CATCH(ReceiveImpl(session_handle, message_buffer.GetPointer(), message_buffer.GetSize())) {
|
||||
R_CATCH(ResultKernelConnectionClosed) {
|
||||
R_CATCH(svc::ResultSessionClosed) {
|
||||
*out_closed = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
*out_closed = false;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Reply(Handle session_handle, const cmif::PointerAndSize &message_buffer) {
|
||||
R_TRY_CATCH(ReplyImpl(session_handle, message_buffer.GetPointer(), message_buffer.GetSize())) {
|
||||
R_CATCH(ResultKernelTimedOut) { return ResultSuccess; }
|
||||
R_CATCH(ResultKernelConnectionClosed) { return ResultSuccess; }
|
||||
R_CONVERT(svc::ResultTimedOut, ResultSuccess())
|
||||
R_CONVERT(svc::ResultSessionClosed, ResultSuccess())
|
||||
} R_END_TRY_CATCH;
|
||||
/* ReplyImpl should *always* return an error. */
|
||||
STS_ASSERT(false);
|
||||
@ -78,9 +78,9 @@ namespace sts::sf::hipc {
|
||||
|
||||
Result CreateSession(Handle *out_server_handle, Handle *out_client_handle) {
|
||||
R_TRY_CATCH(svcCreateSession(out_server_handle, out_client_handle, 0, 0)) {
|
||||
R_CATCH(ResultKernelResourceExhausted) { return ResultHipcOutOfSessions; }
|
||||
R_CONVERT(svc::ResultOutOfResource, sf::hipc::ResultOutOfSessions());
|
||||
} R_END_TRY_CATCH;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace sts::sf::hipc {
|
||||
Result CloneCurrentObjectImpl(Handle *out_client_handle, ServerSessionManager *tagged_manager) {
|
||||
/* Clone the object. */
|
||||
cmif::ServiceObjectHolder &&clone = this->session->srv_obj_holder.Clone();
|
||||
R_UNLESS(clone, ResultHipcDomainObjectNotFound);
|
||||
R_UNLESS(clone, sf::hipc::ResultDomainObjectNotFound());
|
||||
|
||||
/* Create new session handles. */
|
||||
Handle server_handle;
|
||||
@ -52,7 +52,7 @@ namespace sts::sf::hipc {
|
||||
R_ASSERT(tagged_manager->RegisterMitmSession(server_handle, std::move(clone), std::move(new_forward_service)));
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
explicit HipcManager(ServerDomainSessionManager *m, ServerSession *s) : manager(m), session(s), is_mitm_session(s->forward_service != nullptr) {
|
||||
@ -62,7 +62,8 @@ namespace sts::sf::hipc {
|
||||
Result ConvertCurrentObjectToDomain(sf::Out<cmif::DomainObjectId> out) {
|
||||
/* Allocate a domain. */
|
||||
auto domain = this->manager->AllocateDomainServiceObject();
|
||||
R_UNLESS(domain, ResultHipcOutOfDomains);
|
||||
R_UNLESS(domain, sf::hipc::ResultOutOfDomains());
|
||||
auto domain_guard = SCOPE_GUARD { this->manager->FreeDomainServiceObject(domain); };
|
||||
|
||||
cmif::DomainObjectId object_id = cmif::InvalidDomainObjectId;
|
||||
|
||||
@ -71,9 +72,7 @@ namespace sts::sf::hipc {
|
||||
if (this->is_mitm_session) {
|
||||
/* If we're a mitm session, we need to convert the remote session to domain. */
|
||||
STS_ASSERT(session->forward_service->own_handle);
|
||||
R_TRY_CLEANUP(serviceConvertToDomain(session->forward_service.get()), {
|
||||
this->manager->FreeDomainServiceObject(domain);
|
||||
});
|
||||
R_TRY(serviceConvertToDomain(session->forward_service.get()));
|
||||
|
||||
/* The object ID reservation cannot fail here, as that would cause desynchronization from target domain. */
|
||||
object_id = cmif::DomainObjectId{session->forward_service->object_id};
|
||||
@ -99,22 +98,23 @@ namespace sts::sf::hipc {
|
||||
STS_ASSERT(static_cast<bool>(new_holder));
|
||||
|
||||
/* We succeeded! */
|
||||
domain_guard.Cancel();
|
||||
domain->RegisterObject(object_id, std::move(session->srv_obj_holder));
|
||||
session->srv_obj_holder = std::move(new_holder);
|
||||
out.SetValue(object_id);
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CopyFromCurrentDomain(sf::OutMoveHandle out, cmif::DomainObjectId object_id) {
|
||||
/* Get domain. */
|
||||
auto domain = this->session->srv_obj_holder.GetServiceObject<cmif::DomainServiceObject>();
|
||||
R_UNLESS(domain != nullptr, ResultHipcTargetNotDomain);
|
||||
R_UNLESS(domain != nullptr, sf::hipc::ResultTargetNotDomain());
|
||||
|
||||
/* Get domain object. */
|
||||
auto &&object = domain->GetObject(object_id);
|
||||
if (!object) {
|
||||
R_UNLESS(this->is_mitm_session, ResultHipcDomainObjectNotFound);
|
||||
R_UNLESS(this->is_mitm_session, sf::hipc::ResultDomainObjectNotFound());
|
||||
return cmifCopyFromCurrentDomain(this->session->forward_service->session, object_id.value, out.GetHandlePointer());
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ namespace sts::sf::hipc {
|
||||
R_ASSERT(this->manager->RegisterMitmSession(server_handle, std::move(object), std::move(new_forward_service)));
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result CloneCurrentObject(sf::OutMoveHandle out) {
|
||||
|
@ -124,7 +124,12 @@ namespace sts::sf::hipc {
|
||||
std::memcpy(tls_message.GetPointer(), saved_message.GetPointer(), tls_message.GetSize());
|
||||
}
|
||||
|
||||
return this->ProcessRequest(session, tls_message);
|
||||
/* Treat a meta "Context Invalidated" message as a success. */
|
||||
R_TRY_CATCH(this->ProcessRequest(session, tls_message)) {
|
||||
R_CONVERT(sf::impl::ResultRequestInvalidated, ResultSuccess());
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void ServerManagerBase::ProcessDeferredSessions() {
|
||||
@ -135,12 +140,16 @@ namespace sts::sf::hipc {
|
||||
while (it != this->deferred_session_list.end()) {
|
||||
ServerSession *session = static_cast<ServerSession *>(&*it);
|
||||
R_TRY_CATCH(this->ProcessForSession(session)) {
|
||||
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) {
|
||||
R_CATCH(sf::ResultRequestDeferred) {
|
||||
/* Session is still deferred, so let's continue. */
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
/* TODO: N has a result that undefers without success. */
|
||||
R_CATCH(sf::impl::ResultRequestInvalidated) {
|
||||
/* Session is no longer deferred! */
|
||||
it = this->deferred_session_list.erase(it);
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* We succeeded! Remove from deferred list. */
|
||||
@ -159,17 +168,17 @@ namespace sts::sf::hipc {
|
||||
case UserDataTag::Session:
|
||||
/* Try to process for session. */
|
||||
R_TRY_CATCH(this->ProcessForSession(holder)) {
|
||||
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) {
|
||||
R_CATCH(sf::ResultRequestDeferred) {
|
||||
/* The session was deferred, so push it onto the deferred session list. */
|
||||
std::scoped_lock lk(this->deferred_session_mutex);
|
||||
this->deferred_session_list.push_back(*static_cast<ServerSession *>(holder));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* We successfully invoked a command...so let's see if anything can be undeferred. */
|
||||
this->ProcessDeferredSessions();
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
break;
|
||||
STS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace sts::sf::hipc {
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void ServerSessionManager::DestroySession(ServerSession *session) {
|
||||
@ -89,7 +89,7 @@ namespace sts::sf::hipc {
|
||||
session_memory->saved_message = this->GetSessionSavedMessageBuffer(session_memory);
|
||||
/* Register to wait list. */
|
||||
this->RegisterSessionToWaitList(session_memory);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ServerSessionManager::AcceptSessionImpl(ServerSession *session_memory, Handle port_handle, cmif::ServiceObjectHolder &&obj) {
|
||||
@ -105,7 +105,7 @@ namespace sts::sf::hipc {
|
||||
/* Register session. */
|
||||
R_TRY(this->RegisterSessionImpl(session_memory, session_handle, std::forward<cmif::ServiceObjectHolder>(obj)));
|
||||
succeeded = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ServerSessionManager::RegisterMitmSessionImpl(ServerSession *session_memory, Handle mitm_session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
|
||||
@ -119,7 +119,7 @@ namespace sts::sf::hipc {
|
||||
session_memory->pointer_buffer = cmif::PointerAndSize(session_memory->pointer_buffer.GetAddress(), session_memory->forward_service->pointer_buffer_size);
|
||||
/* Register to wait list. */
|
||||
this->RegisterSessionToWaitList(session_memory);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ServerSessionManager::AcceptMitmSessionImpl(ServerSession *session_memory, Handle mitm_port_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
|
||||
@ -135,7 +135,7 @@ namespace sts::sf::hipc {
|
||||
/* Register session. */
|
||||
R_TRY(this->RegisterMitmSessionImpl(session_memory, mitm_session_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv)));
|
||||
succeeded = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ServerSessionManager::RegisterSession(Handle session_handle, cmif::ServiceObjectHolder &&obj) {
|
||||
@ -182,10 +182,10 @@ namespace sts::sf::hipc {
|
||||
switch (recv_result) {
|
||||
case hipc::ReceiveResult::Success:
|
||||
session->is_closed = false;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
case hipc::ReceiveResult::Closed:
|
||||
session->is_closed = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
case hipc::ReceiveResult::NeedsRetry:
|
||||
continue;
|
||||
STS_UNREACHABLE_DEFAULT_CASE();
|
||||
@ -206,29 +206,31 @@ namespace sts::sf::hipc {
|
||||
Result ServerSessionManager::ProcessRequest(ServerSession *session, const cmif::PointerAndSize &message) {
|
||||
if (session->is_closed) {
|
||||
this->CloseSessionImpl(session);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
switch (GetCmifCommandType(message)) {
|
||||
case CmifCommandType_Close:
|
||||
{
|
||||
this->CloseSessionImpl(session);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
default:
|
||||
{
|
||||
R_TRY_CATCH(this->ProcessRequestImpl(session, message, message)) {
|
||||
R_CATCH(ResultServiceFrameworkRequestDeferredByUser) { /* TODO: Properly include entire range Nintendo does */
|
||||
return ResultServiceFrameworkRequestDeferredByUser;
|
||||
R_CATCH(sf::impl::ResultRequestContextChanged) {
|
||||
/* A meta message changing the request context has been sent. */
|
||||
return R_CURRENT_RESULT;
|
||||
}
|
||||
R_CATCH_ALL() {
|
||||
/* All other results indicate something went very wrong. */
|
||||
this->CloseSessionImpl(session);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* We succeeded, so we can process future messages on this session. */
|
||||
this->RegisterSessionToWaitList(session);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,13 +246,13 @@ namespace sts::sf::hipc {
|
||||
case CmifCommandType_ControlWithContext:
|
||||
return this->DispatchManagerRequest(session, in_message, out_message);
|
||||
default:
|
||||
return ResultHipcUnknownCommandType;
|
||||
return sf::hipc::ResultUnknownCommandType();
|
||||
}
|
||||
}
|
||||
|
||||
Result ServerSessionManager::DispatchManagerRequest(ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message) {
|
||||
/* This will get overridden by ... WithDomain class. */
|
||||
return ResultServiceFrameworkNotSupported;
|
||||
return sf::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result ServerSessionManager::DispatchRequest(cmif::ServiceObjectHolder &&obj_holder, ServerSession *session, const cmif::PointerAndSize &in_message, const cmif::PointerAndSize &out_message) {
|
||||
@ -273,10 +275,10 @@ namespace sts::sf::hipc {
|
||||
const uintptr_t in_raw_addr = reinterpret_cast<uintptr_t>(dispatch_ctx.request.data.data_words);
|
||||
const size_t in_raw_size = dispatch_ctx.request.meta.num_data_words * sizeof(u32);
|
||||
/* Note: Nintendo does not validate this size before subtracting 0x10 from it. This is not exploitable. */
|
||||
R_UNLESS(in_raw_size >= 0x10, ResultHipcInvalidRequestSize);
|
||||
R_UNLESS(in_raw_addr + in_raw_size <= in_message_buffer_end, ResultHipcInvalidRequestSize);
|
||||
R_UNLESS(in_raw_size >= 0x10, sf::hipc::ResultInvalidRequestSize());
|
||||
R_UNLESS(in_raw_addr + in_raw_size <= in_message_buffer_end, sf::hipc::ResultInvalidRequestSize());
|
||||
const uintptr_t recv_list_end = reinterpret_cast<uintptr_t>(dispatch_ctx.request.data.recv_list + dispatch_ctx.request.meta.num_recv_statics);
|
||||
R_UNLESS(recv_list_end <= in_message_buffer_end, ResultHipcInvalidRequestSize);
|
||||
R_UNLESS(recv_list_end <= in_message_buffer_end, sf::hipc::ResultInvalidRequestSize());
|
||||
|
||||
/* CMIF has 0x10 of padding in raw data, and requires 0x10 alignment. */
|
||||
const cmif::PointerAndSize in_raw_data(util::AlignUp(in_raw_addr, 0x10), in_raw_size - 0x10);
|
||||
@ -294,7 +296,7 @@ namespace sts::sf::hipc {
|
||||
R_TRY(hipc::Reply(session->session_handle, out_message));
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace sts::sm {
|
||||
void DoWithSessionImpl(void (*Invoker)(void *), void *Function) {
|
||||
impl::DoWithUserSession([&]() {
|
||||
Invoker(Function);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -55,15 +55,15 @@ namespace sts::updater {
|
||||
/* Implementations. */
|
||||
Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size) {
|
||||
if (work_buffer_size < BctSize + EksSize) {
|
||||
return ResultUpdaterTooSmallWorkBuffer;
|
||||
return ResultTooSmallWorkBuffer();
|
||||
}
|
||||
if (reinterpret_cast<uintptr_t>(work_buffer) & 0xFFF) {
|
||||
return ResultUpdaterMisalignedWorkBuffer;
|
||||
if (!util::IsAligned(work_buffer, 0x1000)) {
|
||||
return ResultNotAlignedWorkBuffer();
|
||||
}
|
||||
if (reinterpret_cast<uintptr_t>(work_buffer_size) & 0x1FF) {
|
||||
return ResultUpdaterMisalignedWorkBuffer;
|
||||
if (util::IsAligned(work_buffer_size, 0x200)) {
|
||||
return ResultNotAlignedWorkBuffer();
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
bool HasEks(BootImageUpdateType boot_image_update_type) {
|
||||
@ -115,7 +115,7 @@ namespace sts::updater {
|
||||
/* Read data from save. */
|
||||
out->needs_verify_normal = save.GetNeedsVerification(BootModeType::Normal);
|
||||
out->needs_verify_safe = save.GetNeedsVerification(BootModeType::Safe);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result VerifyBootImagesAndRepairIfNeeded(bool *out_repaired, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) {
|
||||
@ -125,7 +125,7 @@ namespace sts::updater {
|
||||
|
||||
/* Verify the boot images in NAND. */
|
||||
R_TRY_CATCH(VerifyBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type)) {
|
||||
R_CATCH(ResultUpdaterNeedsRepairBootImages) {
|
||||
R_CATCH(ResultNeedsRepairBootImages) {
|
||||
/* Perform repair. */
|
||||
*out_repaired = true;
|
||||
R_TRY(UpdateBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type));
|
||||
@ -153,7 +153,7 @@ namespace sts::updater {
|
||||
u32 total_entries;
|
||||
R_TRY(ncmContentMetaDatabaseList(&meta_db, &total_entries, &written_entries, records, MaxContentMetas * sizeof(*records), title_type, 0, 0, UINT64_MAX, NcmContentInstallType_Full));
|
||||
if (total_entries == 0) {
|
||||
return ResultUpdaterBootImagePackageNotFound;
|
||||
return ResultBootImagePackageNotFound();
|
||||
}
|
||||
|
||||
STS_ASSERT(total_entries == written_entries);
|
||||
@ -166,14 +166,14 @@ namespace sts::updater {
|
||||
|
||||
if (attr & NcmContentMetaAttribute_IncludesExFatDriver) {
|
||||
*out_data_id = records[i].title_id;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's only one entry or no exfat entries, return that entry. */
|
||||
*out_data_id = records[0].title_id;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result VerifyBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) {
|
||||
@ -191,9 +191,7 @@ namespace sts::updater {
|
||||
R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size));
|
||||
|
||||
R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) {
|
||||
R_CATCH(ResultFsTargetNotFound) {
|
||||
return ResultUpdaterBootImagePackageNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); };
|
||||
|
||||
@ -219,26 +217,26 @@ namespace sts::updater {
|
||||
R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size));
|
||||
R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalSub));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
|
||||
/* Compare Package2 Normal/Sub hashes. */
|
||||
R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size));
|
||||
R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalMain));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalSub));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result VerifyBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) {
|
||||
@ -246,9 +244,7 @@ namespace sts::updater {
|
||||
R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size));
|
||||
|
||||
R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) {
|
||||
R_CATCH(ResultFsTargetNotFound) {
|
||||
return ResultUpdaterBootImagePackageNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); };
|
||||
|
||||
@ -279,26 +275,26 @@ namespace sts::updater {
|
||||
R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size));
|
||||
R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeSub));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
|
||||
/* Compare Package2 Normal/Sub hashes. */
|
||||
R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size));
|
||||
R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeMain));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeSub));
|
||||
if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UpdateBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) {
|
||||
@ -316,9 +312,7 @@ namespace sts::updater {
|
||||
R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size));
|
||||
|
||||
R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) {
|
||||
R_CATCH(ResultFsTargetNotFound) {
|
||||
return ResultUpdaterBootImagePackageNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); };
|
||||
|
||||
@ -365,7 +359,7 @@ namespace sts::updater {
|
||||
R_TRY(boot0_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain));
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UpdateBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) {
|
||||
@ -373,9 +367,7 @@ namespace sts::updater {
|
||||
R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size));
|
||||
|
||||
R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) {
|
||||
R_CATCH(ResultFsTargetNotFound) {
|
||||
return ResultUpdaterBootImagePackageNotFound;
|
||||
}
|
||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
ON_SCOPE_EXIT { R_ASSERT(romfsUnmount(GetBootImagePackageMountPath())); };
|
||||
|
||||
@ -426,7 +418,7 @@ namespace sts::updater {
|
||||
R_TRY(boot1_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain));
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SetVerificationNeeded(BootModeType mode, bool needed, void *work_buffer, size_t work_buffer_size) {
|
||||
@ -445,7 +437,7 @@ namespace sts::updater {
|
||||
save.SetNeedsVerification(mode, needed);
|
||||
R_TRY(save.Save());
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result ValidateBctFileHash(Boot0Accessor &accessor, Boot0Partition which, const void *stored_hash, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) {
|
||||
@ -468,10 +460,10 @@ namespace sts::updater {
|
||||
sha256CalculateHash(file_hash, bct, BctSize);
|
||||
|
||||
if (std::memcmp(file_hash, stored_hash, SHA256_HASH_SIZE) != 0) {
|
||||
return ResultUpdaterNeedsRepairBootImages;
|
||||
return ResultNeedsRepairBootImages();
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetPackage2Hash(void *dst_hash, size_t package2_size, void *work_buffer, size_t work_buffer_size, Package2Type which) {
|
||||
@ -518,7 +510,7 @@ namespace sts::updater {
|
||||
|
||||
/* If we don't need to verify anything, we're done. */
|
||||
if (!verification_state.needs_verify_normal && !verification_state.needs_verify_safe) {
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Get a session to ncm. */
|
||||
@ -528,21 +520,17 @@ namespace sts::updater {
|
||||
/* Verify normal, verify safe as needed. */
|
||||
if (verification_state.needs_verify_normal) {
|
||||
R_TRY_CATCH(VerifyBootImagesAndRepairIfNeeded(out_repaired_normal, BootModeType::Normal, work_buffer, work_buffer_size, boot_image_update_type)) {
|
||||
R_CATCH(ResultUpdaterBootImagePackageNotFound) {
|
||||
/* Nintendo considers failure to locate bip a success. TODO: don't do that? */
|
||||
}
|
||||
R_CATCH(ResultBootImagePackageNotFound) { /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ }
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
|
||||
if (verification_state.needs_verify_safe) {
|
||||
R_TRY_CATCH(VerifyBootImagesAndRepairIfNeeded(out_repaired_safe, BootModeType::Safe, work_buffer, work_buffer_size, boot_image_update_type)) {
|
||||
R_CATCH(ResultUpdaterBootImagePackageNotFound) {
|
||||
/* Nintendo considers failure to locate bip a success. TODO: don't do that? */
|
||||
}
|
||||
R_CATCH(ResultBootImagePackageNotFound) { /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ }
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace sts::updater {
|
||||
Result BisAccessor::Initialize() {
|
||||
R_TRY(fsOpenBisStorage(&this->storage, this->partition_id));
|
||||
this->active = true;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void BisAccessor::Finalize() {
|
||||
@ -50,7 +50,7 @@ namespace sts::updater {
|
||||
|
||||
FILE *bip_fp = fopen(bip_path, "rb");
|
||||
if (bip_fp == NULL) {
|
||||
return ResultUpdaterInvalidBootImagePackage;
|
||||
return ResultInvalidBootImagePackage();
|
||||
}
|
||||
ON_SCOPE_EXIT { fclose(bip_fp); };
|
||||
|
||||
@ -73,7 +73,7 @@ namespace sts::updater {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BisAccessor::Clear(u64 offset, u64 size, void *work_buffer, size_t work_buffer_size) {
|
||||
@ -88,7 +88,7 @@ namespace sts::updater {
|
||||
R_TRY(this->Write(offset + written, work_buffer, cur_write_size));
|
||||
written += cur_write_size;
|
||||
}
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BisAccessor::GetHash(void *dst, u64 offset, u64 size, u64 hash_size, void *work_buffer, size_t work_buffer_size) {
|
||||
@ -108,7 +108,7 @@ namespace sts::updater {
|
||||
}
|
||||
sha256ContextGetHash(&sha_ctx, dst);
|
||||
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
size_t Boot0Accessor::GetBootloaderVersion(void *bct) {
|
||||
@ -135,7 +135,7 @@ namespace sts::updater {
|
||||
|
||||
Result Boot0Accessor::UpdateEksManually(void *dst_bct, const void *src_eks) {
|
||||
this->CopyEks(dst_bct, src_eks, GetEksIndex(GetBootloaderVersion(dst_bct)));
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Boot0Accessor::PreserveAutoRcm(void *dst_bct, void *work_buffer, Boot0Partition which) {
|
||||
@ -147,7 +147,7 @@ namespace sts::updater {
|
||||
void *dst_pubk = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(dst_bct) + BctPubkOffset);
|
||||
void *src_pubk = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(work_buffer) + BctPubkOffset);
|
||||
std::memcpy(dst_pubk, src_pubk, BctPubkSize);
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ namespace sts::updater {
|
||||
R_TRY(BisAccessor::Read(dst, entry->size, entry->offset));
|
||||
|
||||
*out_size = entry->size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Write(const void *src, size_t size, EnumType which) {
|
||||
|
@ -39,7 +39,7 @@ namespace sts::updater {
|
||||
|
||||
R_TRY(this->accessor.Initialize());
|
||||
this->save_buffer = work_buffer;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
void BisSave::Finalize() {
|
||||
|
@ -24,7 +24,7 @@ namespace sts::updater {
|
||||
Result ReadFile(size_t *out_size, void *dst, size_t dst_size, const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (fp == NULL) {
|
||||
return ResultUpdaterInvalidBootImagePackage;
|
||||
return ResultInvalidBootImagePackage();
|
||||
}
|
||||
ON_SCOPE_EXIT { fclose(fp); };
|
||||
|
||||
@ -34,13 +34,13 @@ namespace sts::updater {
|
||||
return fsdevGetLastResult();
|
||||
}
|
||||
*out_size = read_size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetFileHash(size_t *out_size, void *dst_hash, const char *path, void *work_buffer, size_t work_buffer_size) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (fp == NULL) {
|
||||
return ResultUpdaterInvalidBootImagePackage;
|
||||
return ResultInvalidBootImagePackage();
|
||||
}
|
||||
ON_SCOPE_EXIT { fclose(fp); };
|
||||
|
||||
@ -66,7 +66,7 @@ namespace sts::updater {
|
||||
|
||||
sha256ContextGetHash(&sha_ctx, dst_hash);
|
||||
*out_size = total_size;
|
||||
return ResultSuccess;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user