fs: implement AccessLog, enable for File operations

This commit is contained in:
Michael Scire 2020-06-29 23:19:33 -07:00 committed by SciresM
parent 3fe7700e5c
commit e2b17086d4
36 changed files with 1930 additions and 362 deletions

View file

@ -19,7 +19,7 @@ export ATMOSPHERE_DEFINES := -DATMOSPHERE
export ATMOSPHERE_SETTINGS := -fPIE -g export ATMOSPHERE_SETTINGS := -fPIE -g
export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \ export ATMOSPHERE_CFLAGS := -Wall -ffunction-sections -fdata-sections -fno-strict-aliasing -fwrapv \
-fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \ -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector \
-Wno-format-truncation -Wno-format-truncation -Wno-format-zero-length
export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20 export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20
export ATMOSPHERE_ASFLAGS := export ATMOSPHERE_ASFLAGS :=

View file

@ -16,7 +16,13 @@
#pragma once #pragma once
#include <stratosphere/fs/fs_common.hpp> #include <stratosphere/fs/fs_common.hpp>
#include <stratosphere/fs/impl/fs_result_utils.hpp>
#include <stratosphere/fs/fs_context.hpp>
#include <stratosphere/fs/fs_result_config.hpp>
#include <stratosphere/fs/fs_storage_type.hpp> #include <stratosphere/fs/fs_storage_type.hpp>
#include <stratosphere/fs/fs_priority.hpp>
#include <stratosphere/fs/impl/fs_priority_utils.hpp>
#include <stratosphere/fs/fs_access_log.hpp>
#include <stratosphere/fs/fsa/fs_ifile.hpp> #include <stratosphere/fs/fsa/fs_ifile.hpp>
#include <stratosphere/fs/fsa/fs_idirectory.hpp> #include <stratosphere/fs/fsa/fs_idirectory.hpp>
#include <stratosphere/fs/fsa/fs_ifilesystem.hpp> #include <stratosphere/fs/fsa/fs_ifilesystem.hpp>
@ -54,3 +60,4 @@
#include <stratosphere/fs/fs_sd_card.hpp> #include <stratosphere/fs/fs_sd_card.hpp>
#include <stratosphere/fs/fs_signed_system_partition.hpp> #include <stratosphere/fs/fs_signed_system_partition.hpp>
#include <stratosphere/fs/fs_system_data.hpp> #include <stratosphere/fs/fs_system_data.hpp>
#include <stratosphere/fs/impl/fs_access_log_impl.hpp>

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018-2020 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 <vapours.hpp>
namespace ams::fs {
enum AccessLogMode : u32 {
AccessLogMode_None = 0,
AccessLogMode_Log = 1,
AccessLogMode_SdCard = 2,
};
Result GetGlobalAccessLogMode(u32 *out);
Result SetGlobalAccessLogMode(u32 mode);
void SetLocalAccessLog(bool enabled);
void SetLocalSystemAccessLogForDebug(bool enabled);
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018-2020 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 <vapours.hpp>
namespace ams::fs {
enum class AbortSpecifier {
Default,
Abort,
Return,
};
using ResultHandler = AbortSpecifier (*)(Result);
class FsContext {
private:
ResultHandler handler;
public:
constexpr explicit FsContext(ResultHandler h) : handler(h) { /* ... */ }
constexpr void SetHandler(ResultHandler h) { this->handler = h; }
constexpr AbortSpecifier HandleResult(Result result) const { return this->handler(result); }
};
void SetDefaultFsContextResultHandler(const ResultHandler handler);
const FsContext *GetCurrentThreadFsContext();
void SetCurrentThreadFsContext(const FsContext *context);
class ScopedFsContext {
private:
const FsContext * const prev_context;
public:
ALWAYS_INLINE ScopedFsContext(const FsContext &ctx) : prev_context(GetCurrentThreadFsContext()) {
SetCurrentThreadFsContext(std::addressof(ctx));
}
ALWAYS_INLINE ~ScopedFsContext() {
SetCurrentThreadFsContext(this->prev_context);
}
};
class ScopedAutoAbortDisabler {
private:
const FsContext * const prev_context;
public:
ScopedAutoAbortDisabler();
ALWAYS_INLINE ~ScopedAutoAbortDisabler() {
SetCurrentThreadFsContext(this->prev_context);
}
};
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2018-2020 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 <vapours.hpp>
namespace ams::fs {
enum Priority {
Priority_Realtime = 0,
Priority_Normal = 1,
Priority_Low = 2,
};
enum PriorityRaw {
PriorityRaw_Realtime = 0,
PriorityRaw_Normal = 1,
PriorityRaw_Low = 2,
PriorityRaw_Background = 3,
};
Priority GetPriorityOnCurrentThread();
Priority GetPriority(os::ThreadType *thread);
PriorityRaw GetPriorityRawOnCurrentThread();
PriorityRaw GetPriorityRaw(os::ThreadType *thread);
void SetPriorityOnCurrentThread(Priority prio);
void SetPriority(os::ThreadType *thread, Priority prio);
void SetPriorityRawOnCurrentThread(PriorityRaw prio);
void SetPriorityRaw(os::ThreadType *thread, PriorityRaw prio);
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2018-2020 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 <vapours.hpp>
namespace ams::fs {
void SetEnabledAutoAbort(bool enabled);
void SetResultHandledByApplication(bool application);
}

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 2018-2020 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 <vapours.hpp>
#include <stratosphere/fs/fs_access_log.hpp>
#include <stratosphere/fs/fs_directory.hpp>
#include <stratosphere/fs/fs_file.hpp>
#include <stratosphere/fs/fs_priority.hpp>
#include <stratosphere/os/os_tick.hpp>
namespace ams::fs::impl {
enum AccessLogTarget : u32 {
AccessLogTarget_None = (0 << 0),
AccessLogTarget_Application = (1 << 0),
AccessLogTarget_System = (1 << 1),
};
struct IdentifyAccessLogHandle {
void *handle;
public:
static constexpr IdentifyAccessLogHandle MakeHandle(void *h) {
return IdentifyAccessLogHandle{h};
}
};
bool IsEnabledAccessLog(u32 target);
bool IsEnabledAccessLog();
bool IsEnabledHandleAccessLog(fs::FileHandle handle);
bool IsEnabledHandleAccessLog(fs::DirectoryHandle handle);
bool IsEnabledHandleAccessLog(fs::impl::IdentifyAccessLogHandle handle);
bool IsEnabledHandleAccessLog(const void *handle);
bool IsEnabledFileSystemAccessorAccessLog(const char *mount_name);
void EnableFileSystemAccessorAccessLog(const char *mount_name);
using AccessLogPrinterCallback = int (*)(char *buffer, size_t buffer_size);
void RegisterStartAccessLogPrinterCallback(AccessLogPrinterCallback callback);
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::impl::IdentifyAccessLogHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
void OutputAccessLog(Result result, fs::Priority priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 7, 8)));
void OutputAccessLog(Result result, fs::PriorityRaw priority_raw, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 7, 8)));
void OutputAccessLogToOnlySdCard(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) __attribute__((format (printf, 6, 7)));
class IdString {
private:
char buffer[0x20];
private:
const char *ToValueString(int id);
public:
template<typename T>
const char *ToString(T id);
};
}
/* Access log components. */
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE ", size: %" PRId64 ""
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE ", offset: %" PRId64 ", size: %zu"
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID ", thread_id: %" PRIu64 ""
/* Access log formats. */
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE ""
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION AMS_FS_IMPL_ACCESS_LOG_FORMAT_OFFSET_AND_SIZE
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_FLUSH_OPTION AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION ", write_option: Flush"
#define AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE(__OPTION__) ((__OPTION__).HasFlushFlag() ? AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_FLUSH_OPTION : AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE_WITH_NO_OPTION)
/* Access log invocation lambdas. */
#define AMS_FS_IMPL_ACCESS_LOG_IMPL(__EXPR__, __HANDLE__, __ENABLED__, __NAME__, ...) \
[&](const char *name) { \
if (!(__ENABLED__)) { \
return (__EXPR__); \
} else { \
const ::ams::os::Tick start = ::ams::os::GetSystemTick(); \
const auto result = (__EXPR__); \
const ::ams::os::Tick end = ::ams::os::GetSystemTick(); \
::ams::fs::impl::OutputAccessLog(result, start, end, name, __HANDLE__, __VA_ARGS__); \
return result; \
} \
}(__NAME__)
#define AMS_FS_IMPL_ACCESS_LOG_WITH_PRIORITY_IMPL(__EXPR__, __PRIORITY__, __HANDLE__, __ENABLED__, __NAME__, ...) \
[&](const char *name) { \
if (!(__ENABLED__)) { \
return (__EXPR__); \
} else { \
const ::ams::os::Tick start = ::ams::os::GetSystemTick(); \
const auto result = (__EXPR__); \
const ::ams::os::Tick end = ::ams::os::GetSystemTick(); \
::ams::fs::impl::OutputAccessLog(result, __PRIORITY__, start, end, name, __HANDLE__, __VA_ARGS__); \
return result; \
} \
}(__NAME__)
#define AMS_FS_IMPL_ACCESS_LOG_EXPLICIT_IMPL(__RESULT__, __START__, __END__, __HANDLE__, __ENABLED__, __NAME__, ...) \
[&](const char *name) { \
if (!(__ENABLED__)) { \
return __RESULT__; \
} else { \
::ams::fs::impl::OutputAccessLog(__RESULT__, __START__, __END__, name, __HANDLE__, __VA_ARGS__); \
return __RESULT__; \
} \
}(__NAME__)
#define AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL(__EXPR__, __ENABLED__, __NAME__, ...) \
[&](const char *name) { \
if (!(__ENABLED__)) { \
return (__EXPR__); \
} else { \
const ::ams::os::Tick start = ::ams::os::GetSystemTick(); \
const auto result = (__EXPR__); \
const ::ams::os::Tick end = ::ams::os::GetSystemTick(); \
::ams::fs::impl::OutputAccessLogUnlessResultSuccess(result, start, end, name, nullptr, __VA_ARGS__); \
return result; \
} \
}(__NAME__)
/* Access log api. */
#define AMS_FS_IMPL_ACCESS_LOG(__EXPR__, __HANDLE__, ...) \
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)
#define AMS_FS_IMPL_ACCESS_LOG_WITH_NAME(__EXPR__, __HANDLE__, __NAME__, ...) \
AMS_FS_IMPL_ACCESS_LOG_IMPL((__EXPR__), __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), __NAME__, __VA_ARGS__)
#define AMS_FS_IMPL_ACCESS_LOG_EXPLICIT(__RESULT__, __START__, __END__, __HANDLE__, __NAME__, ...) \
AMS_FS_IMPL_ACCESS_LOG_EXPLICIT_IMPL((__RESULT__), __START__, __END__, __HANDLE__, ::ams::fs::impl::IsEnabledAccessLog() && ::ams::fs::impl::IsEnabledHandleAccessLog(__HANDLE__), __NAME__, __VA_ARGS__)
#define AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED(__EXPR__, ...) \
AMS_FS_IMPL_ACCESS_LOG_UNLESS_R_SUCCEEDED_IMPL((__EXPR__), ::ams::fs::impl::IsEnabledAccessLog(), AMS_CURRENT_FUNCTION_NAME, __VA_ARGS__)

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/fs/fs_common.hpp>
#include <stratosphere/sf/sf_fs_inline_context.hpp>
namespace ams::fs::impl {
constexpr inline u8 TlsIoPriorityMask = 0x7;
constexpr inline u8 TlsIoRecursiveCallMask = 0x8;
struct TlsIoValueForInheritance {
u8 _tls_value;
};
inline void SetCurrentRequestRecursive() {
os::ThreadType * const cur_thread = os::GetCurrentThread();
sf::SetFsInlineContext(cur_thread, TlsIoRecursiveCallMask | sf::GetFsInlineContext(cur_thread));
}
inline bool IsCurrentRequestRecursive() {
return (sf::GetFsInlineContext(os::GetCurrentThread()) & TlsIoRecursiveCallMask) != 0;
}
inline TlsIoValueForInheritance GetTlsIoValueForInheritance() {
return TlsIoValueForInheritance { sf::GetFsInlineContext(os::GetCurrentThread()) };
}
inline void SetTlsIoValueForInheritance(TlsIoValueForInheritance tls_io) {
sf::SetFsInlineContext(os::GetCurrentThread(), tls_io._tls_value);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/fs/fs_common.hpp>
#include <stratosphere/fs/fs_priority.hpp>
#include <stratosphere/fs/impl/fs_fs_inline_context_utils.hpp>
namespace ams::fs::impl {
enum TlsIoPriority : u8 {
TlsIoPriority_Normal = 0,
TlsIoPriority_Realtime = 1,
TlsIoPriority_Low = 2,
TlsIoPriority_Background = 3,
};
/* Ensure that TlsIo priority matches libnx priority. */
static_assert(TlsIoPriority_Normal == static_cast<TlsIoPriority>(::FsPriority_Normal));
static_assert(TlsIoPriority_Realtime == static_cast<TlsIoPriority>(::FsPriority_Realtime));
static_assert(TlsIoPriority_Low == static_cast<TlsIoPriority>(::FsPriority_Low));
static_assert(TlsIoPriority_Background == static_cast<TlsIoPriority>(::FsPriority_Background));
constexpr inline Result ConvertFsPriorityToTlsIoPriority(u8 *out, PriorityRaw priority) {
AMS_ASSERT(out != nullptr);
switch (priority) {
case PriorityRaw_Normal: *out = TlsIoPriority_Normal;
case PriorityRaw_Realtime: *out = TlsIoPriority_Realtime;
case PriorityRaw_Low: *out = TlsIoPriority_Low;
case PriorityRaw_Background: *out = TlsIoPriority_Background;
default: return fs::ResultInvalidArgument();
}
return ResultSuccess();
}
constexpr inline Result ConvertTlsIoPriorityToFsPriority(PriorityRaw *out, u8 tls_io) {
AMS_ASSERT(out != nullptr);
switch (static_cast<TlsIoPriority>(tls_io)) {
case TlsIoPriority_Normal: *out = PriorityRaw_Normal;
case TlsIoPriority_Realtime: *out = PriorityRaw_Realtime;
case TlsIoPriority_Low: *out = PriorityRaw_Low;
case TlsIoPriority_Background: *out = PriorityRaw_Background;
default: return fs::ResultInvalidArgument();
}
return ResultSuccess();
}
inline u8 GetTlsIoPriority(os::ThreadType *thread) {
return sf::GetFsInlineContext(thread) & TlsIoPriorityMask;
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018-2020 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 <vapours.hpp>
namespace ams::fs::impl {
bool IsAbortNeeded(Result result);
void LogErrorMessage(Result result, const char *function);
}
#define AMS_FS_R_CHECK_ABORT_IMPL(__RESULT__, __FORCE__) \
({ \
if (::ams::fs::impl::IsAbortNeeded(__RESULT__) || (__FORCE__)) { \
::ams::fs::impl::LogErrorMessage(__RESULT__, AMS_CURRENT_FUNCTION_NAME); \
R_ABORT_UNLESS(__RESULT__); \
} \
})
#define AMS_FS_R_TRY(__RESULT__) \
({ \
const ::ams::Result __tmp_fs_result = (__RESULT__); \
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, false); \
R_TRY(__tmp_fs_result); \
})
#define AMS_FS_R_ABORT_UNLESS(__RESULT__) \
({ \
const ::ams::Result __tmp_fs_result = (__RESULT__); \
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, true); \
})
#define AMS_FS_R_THROW(__RESULT__) \
({ \
const ::ams::Result __tmp_fs_result = (__RESULT__); \
AMS_FS_R_CHECK_ABORT_IMPL(__tmp_fs_result, false); \
return __tmp_fs_result; \
})
#define AMS_FS_R_UNLESS(__EXPR__, __RESULT__) \
({ \
if (!(__EXPR__)) { \
AMS_FS_R_THROW((__RESULT__)); \
} \
})
#define AMS_FS_R_TRY_CATCH(__EXPR__) R_TRY_CATCH(__EXPR__)
#define AMS_FS_R_CATCH(...) R_CATCH(__VA_ARGS__)
#define AMS_FS_R_END_TRY_CATCH \
else if (R_FAILED(R_CURRENT_RESULT)) { \
AMS_FS_R_THROW(R_CURRENT_RESULT); \
} \
} \
})
#define AMS_FS_R_END_TRY_CATCH_WITH_ABORT_UNLESS \
else { \
AMS_FS_R_ABORT_UNLESS(R_CURRENT_RESULT); \
} \
} \
})

View file

@ -35,7 +35,8 @@
#include <stratosphere/os/os_system_event.hpp> #include <stratosphere/os/os_system_event.hpp>
#include <stratosphere/os/os_interrupt_event.hpp> #include <stratosphere/os/os_interrupt_event.hpp>
#include <stratosphere/os/os_timer_event.hpp> #include <stratosphere/os/os_timer_event.hpp>
#include <stratosphere/os/os_thread_local_storage_api.hpp> #include <stratosphere/os/os_thread_local_storage.hpp>
#include <stratosphere/os/os_sdk_thread_local_storage.hpp>
#include <stratosphere/os/os_thread.hpp> #include <stratosphere/os/os_thread.hpp>
#include <stratosphere/os/os_message_queue.hpp> #include <stratosphere/os/os_message_queue.hpp>
#include <stratosphere/os/os_waitable.hpp> #include <stratosphere/os/os_waitable.hpp>

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/os/os_thread_local_storage.hpp>
#include <stratosphere/os/os_sdk_thread_local_storage_api.hpp>
namespace ams::os {
class SdkThreadLocalStorage {
NON_COPYABLE(SdkThreadLocalStorage);
NON_MOVEABLE(SdkThreadLocalStorage);
private:
TlsSlot tls_slot;
public:
SdkThreadLocalStorage() {
R_ABORT_UNLESS(os::SdkAllocateTlsSlot(std::addressof(this->tls_slot), nullptr));
}
explicit SdkThreadLocalStorage(TlsDestructor destructor) {
R_ABORT_UNLESS(os::SdkAllocateTlsSlot(std::addressof(this->tls_slot), destructor));
}
~SdkThreadLocalStorage() {
os::FreeTlsSlot(this->tls_slot);
}
uintptr_t GetValue() const { return os::GetTlsValue(this->tls_slot); }
void SetValue(uintptr_t value) { return os::SetTlsValue(this->tls_slot, value); }
TlsSlot GetTlsSlot() const { return this->tls_slot; }
};
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/os/os_common_types.hpp>
#include <stratosphere/os/os_memory_common.hpp>
#include <stratosphere/os/os_thread_local_storage_common.hpp>
namespace ams::os {
Result SdkAllocateTlsSlot(TlsSlot *out, TlsDestructor destructor);
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere/os/os_thread_local_storage_common.hpp>
#include <stratosphere/os/os_thread_local_storage_api.hpp>
namespace ams::os {
class ThreadLocalStorage {
NON_COPYABLE(ThreadLocalStorage);
NON_MOVEABLE(ThreadLocalStorage);
private:
TlsSlot tls_slot;
public:
ThreadLocalStorage() {
R_ABORT_UNLESS(os::AllocateTlsSlot(std::addressof(this->tls_slot), nullptr));
}
explicit ThreadLocalStorage(TlsDestructor destructor) {
R_ABORT_UNLESS(os::AllocateTlsSlot(std::addressof(this->tls_slot), destructor));
}
~ThreadLocalStorage() {
os::FreeTlsSlot(this->tls_slot);
}
uintptr_t GetValue() const { return os::GetTlsValue(this->tls_slot); }
void SetValue(uintptr_t value) { return os::SetTlsValue(this->tls_slot, value); }
TlsSlot GetTlsSlot() const { return this->tls_slot; }
};
}

View file

@ -57,6 +57,12 @@ namespace ams::os {
size_t stack_size; size_t stack_size;
ThreadFunction function; ThreadFunction function;
void *argument; void *argument;
/* NOTE: Here, Nintendo stores the TLS array. This is handled by libnx in our case. */
/* However, we need to access certain values in other threads' TLS (Nintendo uses a hardcoded layout for SDK tls members...) */
/* These members are tls slot holders in sdk code, but just normal thread type members under our scheme. */
uintptr_t atomic_sf_inline_context;
mutable impl::InternalCriticalSectionStorage cs_thread; mutable impl::InternalCriticalSectionStorage cs_thread;
mutable impl::InternalConditionVariableStorage cv_thread; mutable impl::InternalConditionVariableStorage cv_thread;

View file

@ -17,9 +17,15 @@
#pragma once #pragma once
#include <stratosphere/sf/sf_common.hpp> #include <stratosphere/sf/sf_common.hpp>
namespace ams::sf { namespace ams::os {
u8 GetFsInlineContext(); struct ThreadType;
u8 SetFsInlineContext(u8 ctx);
}
namespace ams::sf {
u8 GetFsInlineContext(os::ThreadType *thread);
u8 SetFsInlineContext(os::ThreadType *thread, u8 ctx);
} }

View file

@ -0,0 +1,528 @@
/*
* Copyright (c) 2018-2020 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>
#include "fsa/fs_user_mount_table.hpp"
#include "fsa/fs_directory_accessor.hpp"
#include "fsa/fs_file_accessor.hpp"
#include "fsa/fs_filesystem_accessor.hpp"
#define AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION "ams_version: " STRINGIZE(ATMOSPHERE_RELEASE_VERSION_MAJOR) "." STRINGIZE(ATMOSPHERE_RELEASE_VERSION_MINOR) "." STRINGIZE(ATMOSPHERE_RELEASE_VERSION_MICRO)
/* TODO: Other boards? */
#define AMS_FS_IMPL_ACCESS_LOG_SPEC "spec: NX"
namespace ams::fs {
/* Forward declare priority getter. */
fs::PriorityRaw GetPriorityRawOnCurrentThreadInternal();
namespace {
constinit u32 g_global_access_log_mode = fs::AccessLogMode_None;
constinit u32 g_local_access_log_target = fs::impl::AccessLogTarget_None;
constinit std::atomic_bool g_access_log_initialized = false;
constinit os::SdkMutex g_access_log_initialization_mutex;
void SetLocalAccessLogImpl(bool enabled) {
if (enabled) {
g_local_access_log_target |= fs::impl::AccessLogTarget_Application;
} else {
g_local_access_log_target &= ~fs::impl::AccessLogTarget_Application;
}
}
}
Result GetGlobalAccessLogMode(u32 *out) {
/* Use libnx bindings. */
return ::fsGetGlobalAccessLogMode(out);
}
Result SetGlobalAccessLogMode(u32 mode) {
/* Use libnx bindings. */
return ::fsSetGlobalAccessLogMode(mode);
}
void SetLocalAccessLog(bool enabled) {
SetLocalAccessLogImpl(enabled);
}
void SetLocalApplicationAccessLog(bool enabled) {
SetLocalAccessLogImpl(enabled);
}
void SetLocalSystemAccessLogForDebug(bool enabled) {
#if defined(AMS_BUILD_FOR_DEBUGGING)
if (enabled) {
g_local_access_log_target |= (fs::impl::AccessLogTarget_Application | fs::impl::AccessLogTarget_System);
} else {
g_local_access_log_target &= ~(fs::impl::AccessLogTarget_Application | fs::impl::AccessLogTarget_System);
}
#endif
}
}
namespace ams::fs::impl {
const char *IdString::ToValueString(int id) {
const int len = std::snprintf(this->buffer, sizeof(this->buffer), "%d", id);
AMS_ASSERT(static_cast<size_t>(len) < sizeof(this->buffer));
return this->buffer;
}
template<> const char *IdString::ToString<fs::Priority>(fs::Priority id) {
switch (id) {
case fs::Priority_Realtime: return "Realtime";
case fs::Priority_Normal: return "Normal";
case fs::Priority_Low: return "Low";
default: return ToValueString(static_cast<int>(id));
}
}
template<> const char *IdString::ToString<fs::PriorityRaw>(fs::PriorityRaw id) {
switch (id) {
case fs::PriorityRaw_Realtime: return "Realtime";
case fs::PriorityRaw_Normal: return "Normal";
case fs::PriorityRaw_Low: return "Low";
case fs::PriorityRaw_Background: return "Realtime";
default: return ToValueString(static_cast<int>(id));
}
}
template<> const char *IdString::ToString<fs::ContentStorageId>(fs::ContentStorageId id) {
switch (id) {
case fs::ContentStorageId::User: return "User";
case fs::ContentStorageId::System: return "System";
case fs::ContentStorageId::SdCard: return "SdCard";
default: return ToValueString(static_cast<int>(id));
}
}
template<> const char *IdString::ToString<fs::SaveDataSpaceId>(fs::SaveDataSpaceId id) {
switch (id) {
case fs::SaveDataSpaceId::System: return "System";
case fs::SaveDataSpaceId::User: return "User";
case fs::SaveDataSpaceId::SdSystem: return "SdSystem";
case fs::SaveDataSpaceId::ProperSystem: return "ProperSystem";
default: return ToValueString(static_cast<int>(id));
}
}
template<> const char *IdString::ToString<fs::ContentType>(fs::ContentType id) {
switch (id) {
case fs::ContentType_Meta: return "Meta";
case fs::ContentType_Control: return "Control";
case fs::ContentType_Manual: return "Manual";
case fs::ContentType_Logo: return "Logo";
case fs::ContentType_Data: return "Data";
default: return ToValueString(static_cast<int>(id));
}
}
template<> const char *IdString::ToString<fs::BisPartitionId>(fs::BisPartitionId id) {
switch (id) {
case fs::BisPartitionId::BootPartition1Root: return "BootPartition1Root";
case fs::BisPartitionId::BootPartition2Root: return "BootPartition2Root";
case fs::BisPartitionId::UserDataRoot: return "UserDataRoot";
case fs::BisPartitionId::BootConfigAndPackage2Part1: return "BootConfigAndPackage2Part1";
case fs::BisPartitionId::BootConfigAndPackage2Part2: return "BootConfigAndPackage2Part2";
case fs::BisPartitionId::BootConfigAndPackage2Part3: return "BootConfigAndPackage2Part3";
case fs::BisPartitionId::BootConfigAndPackage2Part4: return "BootConfigAndPackage2Part4";
case fs::BisPartitionId::BootConfigAndPackage2Part5: return "BootConfigAndPackage2Part5";
case fs::BisPartitionId::BootConfigAndPackage2Part6: return "BootConfigAndPackage2Part6";
case fs::BisPartitionId::CalibrationBinary: return "CalibrationBinary";
case fs::BisPartitionId::CalibrationFile: return "CalibrationFile";
case fs::BisPartitionId::SafeMode: return "SafeMode";
case fs::BisPartitionId::User: return "User";
case fs::BisPartitionId::System: return "System";
case fs::BisPartitionId::SystemProperEncryption: return "SystemProperEncryption";
case fs::BisPartitionId::SystemProperPartition: return "SystemProperPartition";
default: return ToValueString(static_cast<int>(id));
}
}
namespace {
class AccessLogPrinterCallbackManager {
private:
AccessLogPrinterCallback callback;
public:
constexpr AccessLogPrinterCallbackManager() : callback(nullptr) { /* ... */ }
constexpr bool IsRegisteredCallback() const { return this->callback != nullptr; }
constexpr void RegisterCallback(AccessLogPrinterCallback c) {
AMS_ASSERT(this->callback == nullptr);
this->callback = c;
}
constexpr int InvokeCallback(char *buf, size_t size) const {
AMS_ASSERT(this->callback != nullptr);
return this->callback(buf, size);
}
};
constinit AccessLogPrinterCallbackManager g_access_log_manager_printer_callback_manager;
ALWAYS_INLINE AccessLogPrinterCallbackManager &GetStartAccessLogPrinterCallbackManager() {
return g_access_log_manager_printer_callback_manager;
}
const char *GetPriorityRawName() {
return fs::impl::IdString().ToString(fs::GetPriorityRawOnCurrentThreadInternal());
}
Result OutputAccessLogToSdCardImpl(const char *log, size_t size) {
/* Use libnx bindings. */
return ::fsOutputAccessLogToSdCard(log, size);
}
void OutputAccessLogToSdCard(const char *format, std::va_list vl) {
if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) {
/* Create a buffer to hold the log's input string. */
int log_buffer_size = 1_KB;
auto log_buffer = fs::impl::MakeUnique<char[]>(log_buffer_size);
while (true) {
if (log_buffer == nullptr) {
return;
}
const auto size = std::vsnprintf(log_buffer.get(), log_buffer_size, format, vl);
if (size < log_buffer_size) {
break;
}
log_buffer_size = size + 1;
log_buffer = fs::impl::MakeUnique<char[]>(log_buffer_size);
}
/* Output. */
OutputAccessLogToSdCardImpl(log_buffer.get(), log_buffer_size - 1);
}
}
void OutputAccessLogImpl(const char *log, size_t size) {
if ((g_global_access_log_mode & AccessLogMode_Log) != 0) {
/* TODO: Support logging. */
} else if ((g_global_access_log_mode & AccessLogMode_SdCard) != 0) {
OutputAccessLogToSdCardImpl(log, size - 1);
}
}
void OutputAccessLog(Result result, const char *priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *format, std::va_list vl) {
/* Create a buffer to hold the log's input string. */
int str_buffer_size = 1_KB;
auto str_buffer = fs::impl::MakeUnique<char[]>(str_buffer_size);
while (true) {
if (str_buffer == nullptr) {
return;
}
const auto size = std::vsnprintf(str_buffer.get(), str_buffer_size, format, vl);
if (size < str_buffer_size) {
break;
}
str_buffer_size = size + 1;
str_buffer = fs::impl::MakeUnique<char[]>(str_buffer_size);
}
/* Create a buffer to hold the log. */
int log_buffer_size = 0;
decltype(str_buffer) log_buffer;
{
/* Declare format string. */
constexpr const char FormatString[] = "FS_ACCESS { "
"start: %9" PRId64 ", "
"end: %9" PRId64 ", "
"result: 0x%08" PRIX32 ", "
"handle: 0x%p, "
"priority: %s, "
"function: \"%s\""
"%s"
" }\n";
/* Convert the timing to ms. */
const s64 start_ms = start.ToTimeSpan().GetMilliSeconds();
const s64 end_ms = end.ToTimeSpan().GetMilliSeconds();
/* Print the log. */
int try_size = std::max<int>(str_buffer_size + sizeof(FormatString) + 0x100, 1_KB);
while (true) {
log_buffer = fs::impl::MakeUnique<char[]>(try_size);
if (log_buffer == nullptr) {
return;
}
log_buffer_size = 1 + std::snprintf(log_buffer.get(), try_size, FormatString, start_ms, end_ms, result.GetValue(), handle, priority, name, str_buffer.get());
if (log_buffer_size <= try_size) {
break;
}
try_size = log_buffer_size;
}
}
OutputAccessLogImpl(log_buffer.get(), log_buffer_size);
}
void GetProgramIndexFortAccessLog(u32 *out_index, u32 *out_count) {
if (hos::GetVersion() >= hos::Version_7_0_0) {
/* Use libnx bindings if available. */
R_ABORT_UNLESS(::fsGetProgramIndexForAccessLog(out_index, out_count));
} else {
/* Use hardcoded defaults. */
*out_index = 0;
*out_count = 0;
}
}
void OutputAccessLogStart() {
/* Get the program index. */
u32 program_index = 0, program_count = 0;
GetProgramIndexFortAccessLog(std::addressof(program_index), std::addressof(program_count));
/* Print the log buffer. */
if (program_count < 2) {
constexpr const char StartLog[] = "FS_ACCESS: { "
AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION ", "
AMS_FS_IMPL_ACCESS_LOG_SPEC
" }\n";
OutputAccessLogImpl(StartLog, sizeof(StartLog));
} else {
constexpr const char StartLog[] = "FS_ACCESS: { "
AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION ", "
AMS_FS_IMPL_ACCESS_LOG_SPEC ", "
"program_index: %d"
" }\n";
char log_buffer[0x80];
const int len = 1 + std::snprintf(log_buffer, sizeof(log_buffer), StartLog, static_cast<int>(program_index));
if (static_cast<size_t>(len) <= sizeof(log_buffer)) {
OutputAccessLogImpl(log_buffer, len);
}
}
}
[[maybe_unused]] void OutputAccessLogStartForSystem() {
constexpr const char StartLog[] = "FS_ACCESS: { "
AMS_FS_IMPL_ACCESS_LOG_AMS_API_VERSION ", "
AMS_FS_IMPL_ACCESS_LOG_SPEC ", "
"for_system: true"
" }\n";
OutputAccessLogImpl(StartLog, sizeof(StartLog));
}
void OutputAccessLogStartGeneratedByCallback() {
/* Get the manager. */
const auto &manager = GetStartAccessLogPrinterCallbackManager();
if (manager.IsRegisteredCallback()) {
/* Invoke the callback. */
char log_buffer[0x80];
const int len = 1 + manager.InvokeCallback(log_buffer, sizeof(log_buffer));
/* Print, if we fit. */
if (static_cast<size_t>(len) <= sizeof(log_buffer)) {
OutputAccessLogImpl(log_buffer, len);
}
}
}
}
bool IsEnabledAccessLog(u32 target) {
/* If we don't need to log to the target, return false. */
if ((g_local_access_log_target & target) == 0) {
return false;
}
/* Ensure we've initialized. */
if (!g_access_log_initialized) {
std::scoped_lock lk(g_access_log_initialization_mutex);
if (!g_access_log_initialized) {
#if defined (AMS_BUILD_FOR_DEBUGGING)
if ((g_local_access_log_target & fs::impl::AccessLogTarget_System) != 0)
{
g_global_access_log_mode = AccessLogMode_Log;
OutputAccessLogStartForSystem();
OutputAccessLogStartGeneratedByCallback();
}
else
#endif
{
AMS_FS_R_ABORT_UNLESS(GetGlobalAccessLogMode(std::addressof(g_global_access_log_mode)));
if (g_global_access_log_mode != AccessLogMode_None) {
OutputAccessLogStart();
OutputAccessLogStartGeneratedByCallback();
}
}
g_access_log_initialized = true;
}
}
return g_global_access_log_mode != AccessLogMode_None;
}
bool IsEnabledAccessLog() {
return IsEnabledAccessLog(fs::impl::AccessLogTarget_Application | fs::impl::AccessLogTarget_System);
}
void RegisterStartAccessLogPrinterCallback(AccessLogPrinterCallback callback) {
GetStartAccessLogPrinterCallbackManager().RegisterCallback(callback);
}
void OutputAccessLog(Result result, fs::Priority priority, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, fs::impl::IdString().ToString(priority), start, end, name, handle, fmt, vl);
va_end(vl);
}
void OutputAccessLog(Result result, fs::PriorityRaw priority_raw, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...){
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, fs::impl::IdString().ToString(priority_raw), start, end, name, handle, fmt, vl);
va_end(vl);
}
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle.handle, fmt, vl);
va_end(vl);
}
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle.handle, fmt, vl);
va_end(vl);
}
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, fs::impl::IdentifyAccessLogHandle handle, const char *fmt, ...) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle.handle, fmt, vl);
va_end(vl);
}
void OutputAccessLog(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle, fmt, vl);
va_end(vl);
}
void OutputAccessLogToOnlySdCard(const char *fmt, ...) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLogToSdCard(fmt, vl);
va_end(vl);
}
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::FileHandle handle, const char *fmt, ...) {
if (R_FAILED(result)) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle.handle, fmt, vl);
va_end(vl);
}
}
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, fs::DirectoryHandle handle, const char *fmt, ...) {
if (R_FAILED(result)) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle.handle, fmt, vl);
va_end(vl);
}
}
void OutputAccessLogUnlessResultSuccess(Result result, os::Tick start, os::Tick end, const char *name, const void *handle, const char *fmt, ...) {
if (R_FAILED(result)) {
std::va_list vl;
va_start(vl, fmt);
OutputAccessLog(result, GetPriorityRawName(), start, end, name, handle, fmt, vl);
va_end(vl);
}
}
bool IsEnabledHandleAccessLog(fs::FileHandle handle) {
/* Get the file accessor. */
impl::FileAccessor *accessor = reinterpret_cast<impl::FileAccessor *>(handle.handle);
if (accessor == nullptr) {
return true;
}
/* Check the parent. */
if (auto *parent = accessor->GetParent(); parent != nullptr) {
return parent->IsEnabledAccessLog();
} else {
return false;
}
}
bool IsEnabledHandleAccessLog(fs::DirectoryHandle handle) {
/* Get the file accessor. */
impl::DirectoryAccessor *accessor = reinterpret_cast<impl::DirectoryAccessor *>(handle.handle);
if (accessor == nullptr) {
return true;
}
/* Check the parent. */
if (auto *parent = accessor->GetParent(); parent != nullptr) {
return parent->IsEnabledAccessLog();
} else {
return false;
}
}
bool IsEnabledHandleAccessLog(fs::impl::IdentifyAccessLogHandle handle) {
return true;
}
bool IsEnabledHandleAccessLog(const void *handle) {
if (handle == nullptr) {
return true;
}
/* We should never receive non-null here. */
AMS_ASSERT(handle == nullptr);
return false;
}
bool IsEnabledFileSystemAccessorAccessLog(const char *mount_name) {
/* Get the accessor. */
impl::FileSystemAccessor *accessor;
if (R_FAILED(impl::Find(std::addressof(accessor), mount_name))) {
return true;
}
return accessor->IsEnabledAccessLog();
}
void EnableFileSystemAccessorAccessLog(const char *mount_name) {
/* Get the accessor. */
impl::FileSystemAccessor *accessor;
AMS_FS_R_ABORT_UNLESS(impl::Find(std::addressof(accessor), mount_name));
accessor->SetAccessLogEnabled(true);
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2018-2020 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 ams::fs {
namespace {
constinit bool g_auto_abort_enabled = true;
/* NOTE: This generates a global constructor. */
os::SdkThreadLocalStorage g_context_tls;
}
void SetEnabledAutoAbort(bool enabled) {
g_auto_abort_enabled = enabled;
}
AbortSpecifier DefaultResultHandler(Result result) {
if (g_auto_abort_enabled) {
return AbortSpecifier::Default;
} else {
return AbortSpecifier::Return;
}
}
AbortSpecifier AlwaysReturnResultHandler(Result result) {
return AbortSpecifier::Return;
}
constinit FsContext g_default_context(DefaultResultHandler);
constinit FsContext g_always_return_context(AlwaysReturnResultHandler);
void SetDefaultFsContextResultHandler(const ResultHandler handler) {
if (handler == nullptr) {
g_default_context.SetHandler(DefaultResultHandler);
} else {
g_default_context.SetHandler(handler);
}
}
const FsContext *GetCurrentThreadFsContext() {
const FsContext *context = reinterpret_cast<const FsContext *>(g_context_tls.GetValue());
if (context == nullptr) {
context = std::addressof(g_default_context);
}
return context;
}
void SetCurrentThreadFsContext(const FsContext *context) {
g_context_tls.SetValue(reinterpret_cast<uintptr_t>(context));
}
ScopedAutoAbortDisabler::ScopedAutoAbortDisabler() : prev_context(GetCurrentThreadFsContext()) {
SetCurrentThreadFsContext(std::addressof(g_always_return_context));
}
}

View file

@ -0,0 +1,160 @@
/*
* Copyright (c) 2018-2020 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 ams::fs {
namespace {
constexpr bool IsValidPriority(fs::Priority priority) {
return priority == Priority_Low || priority == Priority_Normal || priority == Priority_Realtime;
}
constexpr bool IsValidPriorityRaw(fs::PriorityRaw priority_raw) {
return priority_raw == PriorityRaw_Background || priority_raw == PriorityRaw_Low || priority_raw == PriorityRaw_Normal || priority_raw == PriorityRaw_Realtime;
}
fs::PriorityRaw ConvertPriorityToPriorityRaw(fs::Priority priority) {
AMS_ASSERT(IsValidPriority(priority));
switch (priority) {
case Priority_Low: return PriorityRaw_Low;
case Priority_Normal: return PriorityRaw_Normal;
case Priority_Realtime: return PriorityRaw_Realtime;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
fs::Priority ConvertPriorityRawToPriority(fs::PriorityRaw priority_raw) {
AMS_ASSERT(IsValidPriorityRaw(priority_raw));
switch (priority_raw) {
case PriorityRaw_Background: return Priority_Low;
case PriorityRaw_Low: return Priority_Low;
case PriorityRaw_Normal: return Priority_Normal;
case PriorityRaw_Realtime: return Priority_Realtime;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
void UpdateTlsIoPriority(os::ThreadType *thread, u8 tls_io) {
sf::SetFsInlineContext(thread, (tls_io & impl::TlsIoPriorityMask) | (sf::GetFsInlineContext(thread) & ~impl::TlsIoPriorityMask));
}
Result GetPriorityRawImpl(fs::PriorityRaw *out, os::ThreadType *thread) {
/* Validate arguments. */
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
/* Get the raw priority. */
PriorityRaw priority_raw;
R_TRY(impl::ConvertTlsIoPriorityToFsPriority(std::addressof(priority_raw), impl::GetTlsIoPriority(thread)));
/* Set output. */
*out = priority_raw;
return ResultSuccess();
}
Result GetPriorityImpl(fs::Priority *out, os::ThreadType *thread) {
/* Validate arguments. */
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
/* Get the raw priority. */
PriorityRaw priority_raw;
R_TRY(impl::ConvertTlsIoPriorityToFsPriority(std::addressof(priority_raw), impl::GetTlsIoPriority(thread)));
/* Set output. */
*out = ConvertPriorityRawToPriority(priority_raw);
return ResultSuccess();
}
Result SetPriorityRawImpl(os::ThreadType *thread, fs::PriorityRaw priority_raw) {
/* Validate arguments. */
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IsValidPriorityRaw(priority_raw), fs::ResultInvalidArgument());
/* Convert to tls io. */
u8 tls_io;
R_TRY(impl::ConvertFsPriorityToTlsIoPriority(std::addressof(tls_io), priority_raw));
/* Update the priority. */
UpdateTlsIoPriority(thread, tls_io);
return ResultSuccess();
}
Result SetPriorityImpl(os::ThreadType *thread, fs::Priority priority) {
/* Validate arguments. */
R_UNLESS(thread != nullptr, fs::ResultNullptrArgument());
R_UNLESS(IsValidPriority(priority), fs::ResultInvalidArgument());
/* Convert to tls io. */
u8 tls_io;
R_TRY(impl::ConvertFsPriorityToTlsIoPriority(std::addressof(tls_io), ConvertPriorityToPriorityRaw(priority)));
/* Update the priority. */
UpdateTlsIoPriority(thread, tls_io);
return ResultSuccess();
}
}
Priority GetPriorityOnCurrentThread() {
fs::Priority priority;
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityImpl(std::addressof(priority), os::GetCurrentThread()), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
return priority;
}
Priority GetPriority(os::ThreadType *thread) {
fs::Priority priority;
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityImpl(std::addressof(priority), thread), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
return priority;
}
PriorityRaw GetPriorityRawOnCurrentThread() {
fs::PriorityRaw priority_raw;
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityRawImpl(std::addressof(priority_raw), os::GetCurrentThread()), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
return priority_raw;
}
PriorityRaw GetPriorityRawOnCurrentThreadInternal() {
fs::PriorityRaw priority_raw;
AMS_FS_R_ABORT_UNLESS(GetPriorityRawImpl(std::addressof(priority_raw), os::GetCurrentThread()));
return priority_raw;
}
PriorityRaw GetPriorityRaw(os::ThreadType *thread) {
fs::PriorityRaw priority_raw;
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(GetPriorityRawImpl(std::addressof(priority_raw), thread), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
return priority_raw;
}
void SetPriorityOnCurrentThread(Priority priority) {
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityImpl(os::GetCurrentThread(), priority), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
}
void SetPriority(os::ThreadType *thread, Priority priority) {
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityImpl(os::GetCurrentThread(), priority), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
}
void SetPriorityRawOnCurrentThread(PriorityRaw priority_raw) {
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityRawImpl(os::GetCurrentThread(), priority_raw), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
}
void SetPriorityRaw(os::ThreadType *thread, PriorityRaw priority_raw) {
AMS_FS_R_ABORT_UNLESS(AMS_FS_IMPL_ACCESS_LOG(SetPriorityRawImpl(os::GetCurrentThread(), priority_raw), nullptr, AMS_FS_IMPL_ACCESS_LOG_FORMAT_THREAD_ID, thread != nullptr ? os::GetThreadId(thread) : static_cast<os::ThreadId>(0)));
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2018-2020 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 ams::fs {
namespace {
constinit bool g_handled_by_application = false;
}
void SetResultHandledByApplication(bool application) {
g_handled_by_application = application;
}
namespace impl {
bool IsAbortNeeded(Result result) {
/* If the result succeeded, we never need to abort. */
if (R_SUCCEEDED(result)) {
return false;
}
/* Get the abort specifier from current context. */
switch (GetCurrentThreadFsContext()->HandleResult(result)) {
case AbortSpecifier::Default:
if (g_handled_by_application) {
return !fs::ResultHandledByAllProcess::Includes(result);
} else {
return !(fs::ResultHandledByAllProcess::Includes(result) || fs::ResultHandledBySystemProcess::Includes(result));
}
case AbortSpecifier::Abort:
return true;
case AbortSpecifier::Return:
return false;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
void LogResultErrorMessage(Result result) {
/* TODO: log specific results */
}
void LogErrorMessage(Result result, const char *function) {
/* If the result succeeded, there's nothing to log. */
if (R_SUCCEEDED(result)) {
return;
}
/* TODO: Actually log stuff. */
}
}
}

View file

@ -32,7 +32,7 @@ namespace ams::fs::impl {
Result Read(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries); Result Read(s64 *out_count, DirectoryEntry *out_entries, s64 max_entries);
Result GetEntryCount(s64 *out); Result GetEntryCount(s64 *out);
FileSystemAccessor &GetParent() const { return this->parent; } FileSystemAccessor *GetParent() const { return std::addressof(this->parent); }
}; };
} }

View file

@ -71,7 +71,7 @@ namespace ams::fs::impl {
void SetPathBasedFileDataCacheAttachable(bool en) { this->path_cache_attachable = en; } void SetPathBasedFileDataCacheAttachable(bool en) { this->path_cache_attachable = en; }
void SetMultiCommitSupported(bool en) { this->multi_commit_supported = en; } void SetMultiCommitSupported(bool en) { this->multi_commit_supported = en; }
bool IsAccessLogEnabled() const { return this->access_log_enabled; } bool IsEnabledAccessLog() const { return this->access_log_enabled; }
bool IsFileDataCacheAttachable() const { return this->data_cache_attachable; } bool IsFileDataCacheAttachable() const { return this->data_cache_attachable; }
bool IsPathBasedFileDataCacheAttachable() const { return this->path_cache_attachable; } bool IsPathBasedFileDataCacheAttachable() const { return this->path_cache_attachable; }

View file

@ -29,8 +29,8 @@ namespace ams::fs {
Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) { Result ReadFile(FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
size_t read_size; size_t read_size;
R_TRY(ReadFile(std::addressof(read_size), handle, offset, buffer, size, option)); AMS_FS_R_TRY(ReadFile(std::addressof(read_size), handle, offset, buffer, size, option));
R_UNLESS(read_size == size, fs::ResultOutOfRange()); AMS_FS_R_UNLESS(read_size == size, fs::ResultOutOfRange());
return ResultSuccess(); return ResultSuccess();
} }
@ -39,7 +39,8 @@ namespace ams::fs {
} }
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) { Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size, const fs::ReadOption &option) {
return Get(handle)->Read(out, offset, buffer, size, option); AMS_FS_R_TRY(Get(handle)->Read(out, offset, buffer, size, option));
return ResultSuccess();
} }
Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) { Result ReadFile(size_t *out, FileHandle handle, s64 offset, void *buffer, size_t size) {
@ -47,19 +48,23 @@ namespace ams::fs {
} }
Result GetFileSize(s64 *out, FileHandle handle) { Result GetFileSize(s64 *out, FileHandle handle) {
return Get(handle)->GetSize(out); AMS_FS_R_TRY(Get(handle)->GetSize(out));
return ResultSuccess();
} }
Result FlushFile(FileHandle handle) { Result FlushFile(FileHandle handle) {
return Get(handle)->Flush(); AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->Flush(), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE));
return ResultSuccess();
} }
Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) { Result WriteFile(FileHandle handle, s64 offset, const void *buffer, size_t size, const fs::WriteOption &option) {
return Get(handle)->Write(offset, buffer, size, option); AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->Write(offset, buffer, size, option), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_WRITE_FILE(option), offset, size));
return ResultSuccess();
} }
Result SetFileSize(FileHandle handle, s64 size) { Result SetFileSize(FileHandle handle, s64 size) {
return Get(handle)->SetSize(size); AMS_FS_R_TRY(AMS_FS_IMPL_ACCESS_LOG(Get(handle)->SetSize(size), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_SIZE, size));
return ResultSuccess();
} }
int GetFileOpenMode(FileHandle handle) { int GetFileOpenMode(FileHandle handle) {
@ -67,11 +72,12 @@ namespace ams::fs {
} }
void CloseFile(FileHandle handle) { void CloseFile(FileHandle handle) {
delete Get(handle); AMS_FS_IMPL_ACCESS_LOG((delete Get(handle), ResultSuccess()), handle, AMS_FS_IMPL_ACCESS_LOG_FORMAT_NONE);
} }
Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) { Result QueryRange(QueryRangeInfo *out, FileHandle handle, s64 offset, s64 size) {
return Get(handle)->OperateRange(out, sizeof(*out), OperationId::QueryRange, offset, size, nullptr, 0); AMS_FS_R_TRY(Get(handle)->OperateRange(out, sizeof(*out), OperationId::QueryRange, offset, size, nullptr, 0));
return ResultSuccess();
} }
} }

View file

@ -86,7 +86,7 @@ namespace ams::ncm {
Result ReadVariationContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const Path &path, FirmwareVariationId firmware_variation_id) { Result ReadVariationContentMetaInfoList(s32 *out_count, std::unique_ptr<ContentMetaInfo[]> *out_meta_infos, const Path &path, FirmwareVariationId firmware_variation_id) {
AutoBuffer meta; AutoBuffer meta;
{ {
/* TODO: fs::ScopedAutoAbortDisabler aad; */ fs::ScopedAutoAbortDisabler aad;
R_TRY(ReadContentMetaPath(std::addressof(meta), path.str)); R_TRY(ReadContentMetaPath(std::addressof(meta), path.str));
} }

View file

@ -1000,7 +1000,7 @@ namespace ams::ncm {
Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version) { Result InstallTaskBase::GetInstallContentMetaDataFromPath(AutoBuffer *out, const Path &path, const InstallContentInfo &content_info, std::optional<u32> source_version) {
AutoBuffer meta; AutoBuffer meta;
{ {
/* TODO: fs::ScopedAutoAbortDisabler aad; */ fs::ScopedAutoAbortDisabler aad;
R_TRY(ReadContentMetaPath(std::addressof(meta), path.str)); R_TRY(ReadContentMetaPath(std::addressof(meta), path.str));
} }

View file

@ -41,6 +41,9 @@ namespace ams::os::impl {
thread->name_buffer[0] = '\x00'; thread->name_buffer[0] = '\x00';
thread->name_pointer = thread->name_buffer; thread->name_pointer = thread->name_buffer;
/* Set internal tls variables. */
thread->atomic_sf_inline_context = 0;
/* Mark initialized. */ /* Mark initialized. */
thread->state = ThreadType::State_Initialized; thread->state = ThreadType::State_Initialized;
} }

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2018-2020 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 ams::os {
/* TODO: Nintendo reserves half the TLS slots for SDK usage. */
/* We don't have that ability...how should this work? */
Result SdkAllocateTlsSlot(TlsSlot *out, TlsDestructor destructor) {
return os::AllocateTlsSlot(out, destructor);
}
}

View file

@ -21,47 +21,74 @@ namespace ams::sf {
namespace { namespace {
thread_local InlineContext g_inline_context; ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext(os::ThreadType *thread) {
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<uintptr_t>));
return reinterpret_cast<std::atomic<uintptr_t> *>(std::addressof(thread->atomic_sf_inline_context));
}
ALWAYS_INLINE void OnSetInlineContext() { ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext() {
return GetAtomicSfInlineContext(os::GetCurrentThread());
}
ALWAYS_INLINE void OnSetInlineContext(os::ThreadType *thread) {
/* Ensure that libnx receives the priority value. */ /* Ensure that libnx receives the priority value. */
::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext())); ::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext(thread)));
} }
} }
InlineContext GetInlineContext() { InlineContext GetInlineContext() {
/* Get current thread. */
os::ThreadType * const cur_thread = os::GetCurrentThread();
/* Get the context. */
uintptr_t thread_context = GetAtomicSfInlineContext()->load();
/* Copy it out. */
InlineContext ctx; InlineContext ctx;
std::memcpy(std::addressof(ctx), std::addressof(::ams::sf::cmif::g_inline_context), sizeof(ctx)); static_assert(sizeof(ctx) <= sizeof(thread_context));
std::memcpy(std::addressof(ctx), std::addressof(thread_context), sizeof(ctx));
return ctx; return ctx;
} }
InlineContext SetInlineContext(InlineContext ctx) { InlineContext SetInlineContext(InlineContext ctx) {
ON_SCOPE_EXIT { OnSetInlineContext(); }; /* Get current thread. */
static_assert(sizeof(ctx) <= sizeof(g_inline_context)); os::ThreadType * const cur_thread = os::GetCurrentThread();
ON_SCOPE_EXIT { OnSetInlineContext(cur_thread); };
/* Create the new context. */
static_assert(sizeof(ctx) <= sizeof(uintptr_t));
uintptr_t new_context_value = 0;
std::memcpy(std::addressof(new_context_value), std::addressof(ctx), sizeof(ctx));
/* Get the old context. */
uintptr_t old_context_value = GetAtomicSfInlineContext()->exchange(new_context_value);
/* Convert and copy it out. */
InlineContext old_ctx; InlineContext old_ctx;
std::memcpy(std::addressof(old_ctx), std::addressof(g_inline_context), sizeof(old_ctx)); std::memcpy(std::addressof(old_ctx), std::addressof(old_context_value), sizeof(old_ctx));
std::memcpy(std::addressof(g_inline_context), std::addressof(ctx), sizeof(ctx));
return old_ctx; return old_ctx;
} }
} }
u8 GetFsInlineContext() { namespace {
u8 ctx;
std::memcpy(std::addressof(ctx), std::addressof(cmif::g_inline_context), sizeof(ctx)); ALWAYS_INLINE std::atomic<u8> *GetAtomicFsInlineContext(os::ThreadType *thread) {
return ctx; static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<u8>));
return reinterpret_cast<std::atomic<u8> *>(std::addressof(thread->atomic_sf_inline_context));
}
} }
u8 SetFsInlineContext(u8 ctx) { u8 GetFsInlineContext(os::ThreadType *thread) {
ON_SCOPE_EXIT { cmif::OnSetInlineContext(); }; return GetAtomicFsInlineContext(thread)->load();
static_assert(sizeof(ctx) <= sizeof(cmif::g_inline_context)); }
u8 old_ctx; u8 SetFsInlineContext(os::ThreadType *thread, u8 ctx) {
std::memcpy(std::addressof(old_ctx), std::addressof(cmif::g_inline_context), sizeof(old_ctx)); ON_SCOPE_EXIT { cmif::OnSetInlineContext(thread); };
std::memcpy(std::addressof(cmif::g_inline_context), std::addressof(ctx), sizeof(ctx));
return old_ctx; return GetAtomicFsInlineContext(thread)->exchange(ctx);
} }
} }

View file

@ -40,6 +40,9 @@
#define BITSIZEOF(x) (sizeof(x) * CHAR_BIT) #define BITSIZEOF(x) (sizeof(x) * CHAR_BIT)
#define STRINGIZE(x) STRINGIZE_IMPL(x)
#define STRINGIZE_IMPL(x) #x
#ifdef __COUNTER__ #ifdef __COUNTER__
#define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__) #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__)
#else #else

View file

@ -25,6 +25,7 @@
#include <cstring> #include <cstring>
#include <climits> #include <climits>
#include <cctype> #include <cctype>
#include <cinttypes>
/* C++ headers. */ /* C++ headers. */
#include <type_traits> #include <type_traits>

View file

@ -21,386 +21,389 @@ namespace ams::fs {
R_DEFINE_NAMESPACE_RESULT_MODULE(2); R_DEFINE_NAMESPACE_RESULT_MODULE(2);
R_DEFINE_ERROR_RESULT(PathNotFound, 1); R_DEFINE_ERROR_RANGE(HandledByAllProcess, 0, 999);
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2); R_DEFINE_ERROR_RESULT(PathNotFound, 1);
R_DEFINE_ERROR_RESULT(PathAlreadyExists, 2);
R_DEFINE_ERROR_RESULT(TargetLocked, 7); R_DEFINE_ERROR_RESULT(TargetLocked, 7);
R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8); R_DEFINE_ERROR_RESULT(DirectoryNotEmpty, 8);
R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45); R_DEFINE_ERROR_RANGE (NotEnoughFreeSpace, 30, 45);
R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38); R_DEFINE_ERROR_RANGE(NotEnoughFreeSpaceBis, 34, 38);
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35); R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisCalibration, 35);
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36); R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSafe, 36);
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37); R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisUser, 37);
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38); R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceBisSystem, 38);
R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39); R_DEFINE_ERROR_RESULT(NotEnoughFreeSpaceSdCard, 39);
R_DEFINE_ERROR_RESULT(UnsupportedSdkVersion, 50); R_DEFINE_ERROR_RESULT(UnsupportedSdkVersion, 50);
R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60); R_DEFINE_ERROR_RESULT(MountNameAlreadyExists, 60);
R_DEFINE_ERROR_RESULT(PartitionNotFound, 1001); R_DEFINE_ERROR_RANGE(HandledBySystemProcess, 1000, 2999);
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002); R_DEFINE_ERROR_RESULT(PartitionNotFound, 1001);
R_DEFINE_ERROR_RESULT(TargetNotFound, 1002);
R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499); R_DEFINE_ERROR_RANGE(SdCardAccessFailed, 2000, 2499);
R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001); R_DEFINE_ERROR_RESULT(SdCardNotPresent, 2001);
R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999); R_DEFINE_ERROR_RANGE(GameCardAccessFailed, 2500, 2999);
R_DEFINE_ERROR_RESULT(NotImplemented, 3001); R_DEFINE_ERROR_RESULT(NotImplemented, 3001);
R_DEFINE_ERROR_RESULT(UnsupportedVersion, 3002); R_DEFINE_ERROR_RESULT(UnsupportedVersion, 3002);
R_DEFINE_ERROR_RESULT(OutOfRange, 3005); R_DEFINE_ERROR_RESULT(OutOfRange, 3005);
R_DEFINE_ERROR_RESULT(SystemPartitionNotReady, 3100); R_DEFINE_ERROR_RESULT(SystemPartitionNotReady, 3100);
R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499); R_DEFINE_ERROR_RANGE(AllocationFailure, 3200, 3499);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorA, 3211); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorA, 3211);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorB, 3212); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemAccessorB, 3212);
R_DEFINE_ERROR_RESULT(AllocationFailureInApplicationA, 3213); R_DEFINE_ERROR_RESULT(AllocationFailureInApplicationA, 3213);
R_DEFINE_ERROR_RESULT(AllocationFailureInBisA, 3215); R_DEFINE_ERROR_RESULT(AllocationFailureInBisA, 3215);
R_DEFINE_ERROR_RESULT(AllocationFailureInBisB, 3216); R_DEFINE_ERROR_RESULT(AllocationFailureInBisB, 3216);
R_DEFINE_ERROR_RESULT(AllocationFailureInBisC, 3217); R_DEFINE_ERROR_RESULT(AllocationFailureInBisC, 3217);
R_DEFINE_ERROR_RESULT(AllocationFailureInCodeA, 3218); R_DEFINE_ERROR_RESULT(AllocationFailureInCodeA, 3218);
R_DEFINE_ERROR_RESULT(AllocationFailureInContentA, 3219); R_DEFINE_ERROR_RESULT(AllocationFailureInContentA, 3219);
R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageA, 3220); R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageA, 3220);
R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageB, 3221); R_DEFINE_ERROR_RESULT(AllocationFailureInContentStorageB, 3221);
R_DEFINE_ERROR_RESULT(AllocationFailureInDataA, 3222); R_DEFINE_ERROR_RESULT(AllocationFailureInDataA, 3222);
R_DEFINE_ERROR_RESULT(AllocationFailureInDataB, 3223); R_DEFINE_ERROR_RESULT(AllocationFailureInDataB, 3223);
R_DEFINE_ERROR_RESULT(AllocationFailureInDeviceSaveDataA, 3224); R_DEFINE_ERROR_RESULT(AllocationFailureInDeviceSaveDataA, 3224);
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardA, 3225); R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardA, 3225);
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardB, 3226); R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardB, 3226);
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardC, 3227); R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardC, 3227);
R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardD, 3228); R_DEFINE_ERROR_RESULT(AllocationFailureInGameCardD, 3228);
R_DEFINE_ERROR_RESULT(AllocationFailureInImageDirectoryA, 3232); R_DEFINE_ERROR_RESULT(AllocationFailureInImageDirectoryA, 3232);
R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardA, 3244); R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardA, 3244);
R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardB, 3245); R_DEFINE_ERROR_RESULT(AllocationFailureInSdCardB, 3245);
R_DEFINE_ERROR_RESULT(AllocationFailureInSystemSaveDataA, 3246); R_DEFINE_ERROR_RESULT(AllocationFailureInSystemSaveDataA, 3246);
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemA, 3247); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemA, 3247);
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemB, 3248); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemB, 3248);
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemC, 3249); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemC, 3249);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplD, 3256); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplD, 3256);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplE, 3257); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemProxyCoreImplE, 3257);
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemCreatorA, 3280); R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemCreatorA, 3280);
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFileSystemCreatorA, 3281); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFileSystemCreatorA, 3281);
R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorA, 3288); R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorA, 3288);
R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorB, 3289); R_DEFINE_ERROR_RESULT(AllocationFailureInStorageOnNcaCreatorB, 3289);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBuddyHeapA, 3294); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBuddyHeapA, 3294);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBufferManagerA, 3295); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemBufferManagerA, 3295);
R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageA, 3296); R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageA, 3296);
R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageB, 3297); R_DEFINE_ERROR_RESULT(AllocationFailureInBlockCacheBufferedStorageB, 3297);
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageA, 3304); R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageA, 3304);
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageB, 3305); R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityVerificationStorageB, 3305);
R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321); R_DEFINE_ERROR_RESULT(AllocationFailureInDirectorySaveDataFileSystem, 3321);
R_DEFINE_ERROR_RESULT(AllocationFailureInNcaFileSystemDriverI, 3341); R_DEFINE_ERROR_RESULT(AllocationFailureInNcaFileSystemDriverI, 3341);
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemA, 3347); R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemA, 3347);
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemB, 3348); R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemB, 3348);
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemC, 3349); R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemC, 3349);
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaA, 3350); R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaA, 3350);
R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaB, 3351); R_DEFINE_ERROR_RESULT(AllocationFailureInPartitionFileSystemMetaB, 3351);
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemD, 3352); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemD, 3352);
R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355); R_DEFINE_ERROR_RESULT(AllocationFailureInSubDirectoryFileSystem, 3355);
R_DEFINE_ERROR_RESULT(AllocationFailureInNcaReaderA, 3363); R_DEFINE_ERROR_RESULT(AllocationFailureInNcaReaderA, 3363);
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterA, 3365); R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterA, 3365);
R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterB, 3366); R_DEFINE_ERROR_RESULT(AllocationFailureInRegisterB, 3366);
R_DEFINE_ERROR_RESULT(AllocationFailureInPathNormalizer, 3367); R_DEFINE_ERROR_RESULT(AllocationFailureInPathNormalizer, 3367);
R_DEFINE_ERROR_RESULT(AllocationFailureInDbmRomKeyValueStorage, 3375); R_DEFINE_ERROR_RESULT(AllocationFailureInDbmRomKeyValueStorage, 3375);
R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemE, 3377); R_DEFINE_ERROR_RESULT(AllocationFailureInRomFsFileSystemE, 3377);
R_DEFINE_ERROR_RESULT(AllocationFailureInReadOnlyFileSystemA, 3386); R_DEFINE_ERROR_RESULT(AllocationFailureInReadOnlyFileSystemA, 3386);
R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageA, 3399); R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageA, 3399);
R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageB, 3400); R_DEFINE_ERROR_RESULT(AllocationFailureInAesCtrCounterExtendedStorageB, 3400);
R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemInterfaceAdapter, 3407); R_DEFINE_ERROR_RESULT(AllocationFailureInFileSystemInterfaceAdapter, 3407);
R_DEFINE_ERROR_RESULT(AllocationFailureInBufferedStorageA, 3411); R_DEFINE_ERROR_RESULT(AllocationFailureInBufferedStorageA, 3411);
R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityRomFsStorageA, 3412); R_DEFINE_ERROR_RESULT(AllocationFailureInIntegrityRomFsStorageA, 3412);
R_DEFINE_ERROR_RESULT(AllocationFailureInNew, 3420); R_DEFINE_ERROR_RESULT(AllocationFailureInNew, 3420);
R_DEFINE_ERROR_RESULT(AllocationFailureInMakeUnique, 3422); R_DEFINE_ERROR_RESULT(AllocationFailureInMakeUnique, 3422);
R_DEFINE_ERROR_RESULT(AllocationFailureInAllocateShared, 3423); R_DEFINE_ERROR_RESULT(AllocationFailureInAllocateShared, 3423);
R_DEFINE_ERROR_RESULT(AllocationFailurePooledBufferNotEnoughSize, 3424); R_DEFINE_ERROR_RESULT(AllocationFailurePooledBufferNotEnoughSize, 3424);
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999); R_DEFINE_ERROR_RANGE(Internal, 3000, 7999);
R_DEFINE_ERROR_RANGE(MmcAccessFailed, 3500, 3999);
R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999); R_DEFINE_ERROR_RANGE(DataCorrupted, 4000, 4999);
R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299); R_DEFINE_ERROR_RANGE(RomCorrupted, 4001, 4299);
R_DEFINE_ERROR_RESULT(UnsupportedRomVersion, 4002); R_DEFINE_ERROR_RESULT(UnsupportedRomVersion, 4002);
R_DEFINE_ERROR_RANGE(AesCtrCounterExtendedStorageCorrupted, 4011, 4019); R_DEFINE_ERROR_RANGE(AesCtrCounterExtendedStorageCorrupted, 4011, 4019);
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedEntryOffset, 4012); R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedEntryOffset, 4012);
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedTableSize, 4013); R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedTableSize, 4013);
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedGeneration, 4014); R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedGeneration, 4014);
R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedOffset, 4015); R_DEFINE_ERROR_RESULT(InvalidAesCtrCounterExtendedOffset, 4015);
R_DEFINE_ERROR_RANGE(IndirectStorageCorrupted, 4021, 4029); R_DEFINE_ERROR_RANGE(IndirectStorageCorrupted, 4021, 4029);
R_DEFINE_ERROR_RESULT(InvalidIndirectEntryOffset, 4022); R_DEFINE_ERROR_RESULT(InvalidIndirectEntryOffset, 4022);
R_DEFINE_ERROR_RESULT(InvalidIndirectEntryStorageIndex, 4023); R_DEFINE_ERROR_RESULT(InvalidIndirectEntryStorageIndex, 4023);
R_DEFINE_ERROR_RESULT(InvalidIndirectStorageSize, 4024); R_DEFINE_ERROR_RESULT(InvalidIndirectStorageSize, 4024);
R_DEFINE_ERROR_RESULT(InvalidIndirectVirtualOffset, 4025); R_DEFINE_ERROR_RESULT(InvalidIndirectVirtualOffset, 4025);
R_DEFINE_ERROR_RESULT(InvalidIndirectPhysicalOffset, 4026); R_DEFINE_ERROR_RESULT(InvalidIndirectPhysicalOffset, 4026);
R_DEFINE_ERROR_RESULT(InvalidIndirectStorageIndex, 4027); R_DEFINE_ERROR_RESULT(InvalidIndirectStorageIndex, 4027);
R_DEFINE_ERROR_RANGE(BucketTreeCorrupted, 4031, 4039); R_DEFINE_ERROR_RANGE(BucketTreeCorrupted, 4031, 4039);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeSignature, 4032); R_DEFINE_ERROR_RESULT(InvalidBucketTreeSignature, 4032);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryCount, 4033); R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryCount, 4033);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeEntryCount, 4034); R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeEntryCount, 4034);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeOffset, 4035); R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeOffset, 4035);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryOffset, 4036); R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntryOffset, 4036);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntrySetOffset, 4037); R_DEFINE_ERROR_RESULT(InvalidBucketTreeEntrySetOffset, 4037);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeIndex, 4038); R_DEFINE_ERROR_RESULT(InvalidBucketTreeNodeIndex, 4038);
R_DEFINE_ERROR_RESULT(InvalidBucketTreeVirtualOffset, 4039); R_DEFINE_ERROR_RESULT(InvalidBucketTreeVirtualOffset, 4039);
R_DEFINE_ERROR_RANGE(RomNcaCorrupted, 4041, 4139); R_DEFINE_ERROR_RANGE(RomNcaCorrupted, 4041, 4139);
R_DEFINE_ERROR_RANGE(RomNcaFileSystemCorrupted, 4051, 4069); R_DEFINE_ERROR_RANGE(RomNcaFileSystemCorrupted, 4051, 4069);
R_DEFINE_ERROR_RESULT(InvalidRomNcaFileSystemType, 4052); R_DEFINE_ERROR_RESULT(InvalidRomNcaFileSystemType, 4052);
R_DEFINE_ERROR_RESULT(InvalidRomAcidFileSize, 4053); R_DEFINE_ERROR_RESULT(InvalidRomAcidFileSize, 4053);
R_DEFINE_ERROR_RESULT(InvalidRomAcidSize, 4054); R_DEFINE_ERROR_RESULT(InvalidRomAcidSize, 4054);
R_DEFINE_ERROR_RESULT(InvalidRomAcid, 4055); R_DEFINE_ERROR_RESULT(InvalidRomAcid, 4055);
R_DEFINE_ERROR_RESULT(RomAcidVerificationFailed, 4056); R_DEFINE_ERROR_RESULT(RomAcidVerificationFailed, 4056);
R_DEFINE_ERROR_RESULT(InvalidRomNcaSignature, 4057); R_DEFINE_ERROR_RESULT(InvalidRomNcaSignature, 4057);
R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature1VerificationFailed, 4058); R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature1VerificationFailed, 4058);
R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature2VerificationFailed, 4059); R_DEFINE_ERROR_RESULT(RomNcaHeaderSignature2VerificationFailed, 4059);
R_DEFINE_ERROR_RESULT(RomNcaFsHeaderHashVerificationFailed, 4060); R_DEFINE_ERROR_RESULT(RomNcaFsHeaderHashVerificationFailed, 4060);
R_DEFINE_ERROR_RESULT(InvalidRomNcaKeyIndex, 4061); R_DEFINE_ERROR_RESULT(InvalidRomNcaKeyIndex, 4061);
R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderHashType, 4062); R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderHashType, 4062);
R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderEncryptionType, 4063); R_DEFINE_ERROR_RESULT(InvalidRomNcaFsHeaderEncryptionType, 4063);
R_DEFINE_ERROR_RANGE(RomNcaHierarchicalSha256StorageCorrupted, 4071, 4079); R_DEFINE_ERROR_RANGE(RomNcaHierarchicalSha256StorageCorrupted, 4071, 4079);
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256BlockSize, 4072); R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256BlockSize, 4072);
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256LayerCount, 4073); R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalSha256LayerCount, 4073);
R_DEFINE_ERROR_RESULT(RomHierarchicalSha256BaseStorageTooLarge, 4074); R_DEFINE_ERROR_RESULT(RomHierarchicalSha256BaseStorageTooLarge, 4074);
R_DEFINE_ERROR_RESULT(RomHierarchicalSha256HashVerificationFailed, 4075); R_DEFINE_ERROR_RESULT(RomHierarchicalSha256HashVerificationFailed, 4075);
R_DEFINE_ERROR_RANGE(RomIntegrityVerificationStorageCorrupted, 4141, 4179); R_DEFINE_ERROR_RANGE(RomIntegrityVerificationStorageCorrupted, 4141, 4179);
R_DEFINE_ERROR_RESULT(IncorrectRomIntegrityVerificationMagic, 4142); R_DEFINE_ERROR_RESULT(IncorrectRomIntegrityVerificationMagic, 4142);
R_DEFINE_ERROR_RESULT(InvalidRomZeroHash, 4143); R_DEFINE_ERROR_RESULT(InvalidRomZeroHash, 4143);
R_DEFINE_ERROR_RESULT(RomNonRealDataVerificationFailed, 4144); R_DEFINE_ERROR_RESULT(RomNonRealDataVerificationFailed, 4144);
R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalIntegrityVerificationLayerCount, 4145); R_DEFINE_ERROR_RESULT(InvalidRomHierarchicalIntegrityVerificationLayerCount, 4145);
R_DEFINE_ERROR_RANGE(RomRealDataVerificationFailed, 4151, 4159); R_DEFINE_ERROR_RANGE(RomRealDataVerificationFailed, 4151, 4159);
R_DEFINE_ERROR_RESULT(ClearedRomRealDataVerificationFailed, 4152); R_DEFINE_ERROR_RESULT(ClearedRomRealDataVerificationFailed, 4152);
R_DEFINE_ERROR_RESULT(UnclearedRomRealDataVerificationFailed, 4153); R_DEFINE_ERROR_RESULT(UnclearedRomRealDataVerificationFailed, 4153);
R_DEFINE_ERROR_RANGE(RomPartitionFileSystemCorrupted, 4181, 4199); R_DEFINE_ERROR_RANGE(RomPartitionFileSystemCorrupted, 4181, 4199);
R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionHashTarget, 4182); R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionHashTarget, 4182);
R_DEFINE_ERROR_RESULT(RomSha256PartitionHashVerificationFailed, 4183); R_DEFINE_ERROR_RESULT(RomSha256PartitionHashVerificationFailed, 4183);
R_DEFINE_ERROR_RESULT(RomPartitionSignatureVerificationFailed, 4184); R_DEFINE_ERROR_RESULT(RomPartitionSignatureVerificationFailed, 4184);
R_DEFINE_ERROR_RESULT(RomSha256PartitionSignatureVerificationFailed, 4185); R_DEFINE_ERROR_RESULT(RomSha256PartitionSignatureVerificationFailed, 4185);
R_DEFINE_ERROR_RESULT(InvalidRomPartitionEntryOffset, 4186); R_DEFINE_ERROR_RESULT(InvalidRomPartitionEntryOffset, 4186);
R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionMetaDataSize, 4187); R_DEFINE_ERROR_RESULT(InvalidRomSha256PartitionMetaDataSize, 4187);
R_DEFINE_ERROR_RANGE(RomBuiltInStorageCorrupted, 4201, 4219); R_DEFINE_ERROR_RANGE(RomBuiltInStorageCorrupted, 4201, 4219);
R_DEFINE_ERROR_RESULT(RomGptHeaderVerificationFailed, 4202); R_DEFINE_ERROR_RESULT(RomGptHeaderVerificationFailed, 4202);
R_DEFINE_ERROR_RANGE(RomHostFileSystemCorrupted, 4241, 4259); R_DEFINE_ERROR_RANGE(RomHostFileSystemCorrupted, 4241, 4259);
R_DEFINE_ERROR_RESULT(RomHostEntryCorrupted, 4242); R_DEFINE_ERROR_RESULT(RomHostEntryCorrupted, 4242);
R_DEFINE_ERROR_RESULT(RomHostFileDataCorrupted, 4243); R_DEFINE_ERROR_RESULT(RomHostFileDataCorrupted, 4243);
R_DEFINE_ERROR_RESULT(RomHostFileCorrupted, 4244); R_DEFINE_ERROR_RESULT(RomHostFileCorrupted, 4244);
R_DEFINE_ERROR_RESULT(InvalidRomHostHandle, 4245); R_DEFINE_ERROR_RESULT(InvalidRomHostHandle, 4245);
R_DEFINE_ERROR_RANGE(RomDatabaseCorrupted, 4261, 4279); R_DEFINE_ERROR_RANGE(RomDatabaseCorrupted, 4261, 4279);
R_DEFINE_ERROR_RESULT(InvalidRomAllocationTableBlock, 4262); R_DEFINE_ERROR_RESULT(InvalidRomAllocationTableBlock, 4262);
R_DEFINE_ERROR_RESULT(InvalidRomKeyValueListElementIndex, 4263); R_DEFINE_ERROR_RESULT(InvalidRomKeyValueListElementIndex, 4263);
R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499); R_DEFINE_ERROR_RANGE(SaveDataCorrupted, 4301, 4499);
R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599); R_DEFINE_ERROR_RANGE(NcaCorrupted, 4501, 4599);
R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeA, 4508); R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeA, 4508);
R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeB, 4509); R_DEFINE_ERROR_RESULT(NcaBaseStorageOutOfRangeB, 4509);
R_DEFINE_ERROR_RANGE(NcaFileSystemCorrupted, 4511, 4529); R_DEFINE_ERROR_RANGE(NcaFileSystemCorrupted, 4511, 4529);
R_DEFINE_ERROR_RESULT(InvalidNcaFileSystemType, 4512); R_DEFINE_ERROR_RESULT(InvalidNcaFileSystemType, 4512);
R_DEFINE_ERROR_RESULT(InvalidAcidFileSize, 4513); R_DEFINE_ERROR_RESULT(InvalidAcidFileSize, 4513);
R_DEFINE_ERROR_RESULT(InvalidAcidSize, 4514); R_DEFINE_ERROR_RESULT(InvalidAcidSize, 4514);
R_DEFINE_ERROR_RESULT(InvalidAcid, 4515); R_DEFINE_ERROR_RESULT(InvalidAcid, 4515);
R_DEFINE_ERROR_RESULT(AcidVerificationFailed, 4516); R_DEFINE_ERROR_RESULT(AcidVerificationFailed, 4516);
R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 4517); R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 4517);
R_DEFINE_ERROR_RESULT(NcaHeaderSignature1VerificationFailed, 4518); R_DEFINE_ERROR_RESULT(NcaHeaderSignature1VerificationFailed, 4518);
R_DEFINE_ERROR_RESULT(NcaHeaderSignature2VerificationFailed, 4519); R_DEFINE_ERROR_RESULT(NcaHeaderSignature2VerificationFailed, 4519);
R_DEFINE_ERROR_RESULT(NcaFsHeaderHashVerificationFailed, 4520); R_DEFINE_ERROR_RESULT(NcaFsHeaderHashVerificationFailed, 4520);
R_DEFINE_ERROR_RESULT(InvalidNcaKeyIndex, 4521); R_DEFINE_ERROR_RESULT(InvalidNcaKeyIndex, 4521);
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderHashType, 4522); R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderHashType, 4522);
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderEncryptionType, 4523); R_DEFINE_ERROR_RESULT(InvalidNcaFsHeaderEncryptionType, 4523);
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoIndirectSize, 4524); R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoIndirectSize, 4524);
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExSize, 4525); R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExSize, 4525);
R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExOffset, 4526); R_DEFINE_ERROR_RESULT(InvalidNcaPatchInfoAesCtrExOffset, 4526);
R_DEFINE_ERROR_RESULT(InvalidNcaId, 4527); R_DEFINE_ERROR_RESULT(InvalidNcaId, 4527);
R_DEFINE_ERROR_RESULT(InvalidNcaHeader, 4528); R_DEFINE_ERROR_RESULT(InvalidNcaHeader, 4528);
R_DEFINE_ERROR_RESULT(InvalidNcaFsHeader, 4529); R_DEFINE_ERROR_RESULT(InvalidNcaFsHeader, 4529);
R_DEFINE_ERROR_RANGE(NcaHierarchicalSha256StorageCorrupted, 4531, 4539); R_DEFINE_ERROR_RANGE(NcaHierarchicalSha256StorageCorrupted, 4531, 4539);
R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256BlockSize, 4532); R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256BlockSize, 4532);
R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256LayerCount, 4533); R_DEFINE_ERROR_RESULT(InvalidHierarchicalSha256LayerCount, 4533);
R_DEFINE_ERROR_RESULT(HierarchicalSha256BaseStorageTooLarge, 4534); R_DEFINE_ERROR_RESULT(HierarchicalSha256BaseStorageTooLarge, 4534);
R_DEFINE_ERROR_RESULT(HierarchicalSha256HashVerificationFailed, 4535); R_DEFINE_ERROR_RESULT(HierarchicalSha256HashVerificationFailed, 4535);
/* TODO: Range? */ /* TODO: Range? */
R_DEFINE_ERROR_RESULT(InvalidNcaHeader1SignatureKeyGeneration, 4543); R_DEFINE_ERROR_RESULT(InvalidNcaHeader1SignatureKeyGeneration, 4543);
R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639); R_DEFINE_ERROR_RANGE(IntegrityVerificationStorageCorrupted, 4601, 4639);
R_DEFINE_ERROR_RESULT(IncorrectIntegrityVerificationMagic, 4602); R_DEFINE_ERROR_RESULT(IncorrectIntegrityVerificationMagic, 4602);
R_DEFINE_ERROR_RESULT(InvalidZeroHash, 4603); R_DEFINE_ERROR_RESULT(InvalidZeroHash, 4603);
R_DEFINE_ERROR_RESULT(NonRealDataVerificationFailed, 4604); R_DEFINE_ERROR_RESULT(NonRealDataVerificationFailed, 4604);
R_DEFINE_ERROR_RESULT(InvalidHierarchicalIntegrityVerificationLayerCount, 4605); R_DEFINE_ERROR_RESULT(InvalidHierarchicalIntegrityVerificationLayerCount, 4605);
R_DEFINE_ERROR_RANGE(RealDataVerificationFailed, 4611, 4619); R_DEFINE_ERROR_RANGE(RealDataVerificationFailed, 4611, 4619);
R_DEFINE_ERROR_RESULT(ClearedRealDataVerificationFailed, 4612); R_DEFINE_ERROR_RESULT(ClearedRealDataVerificationFailed, 4612);
R_DEFINE_ERROR_RESULT(UnclearedRealDataVerificationFailed, 4613); R_DEFINE_ERROR_RESULT(UnclearedRealDataVerificationFailed, 4613);
R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659); R_DEFINE_ERROR_RANGE(PartitionFileSystemCorrupted, 4641, 4659);
R_DEFINE_ERROR_RESULT(InvalidSha256PartitionHashTarget, 4642); R_DEFINE_ERROR_RESULT(InvalidSha256PartitionHashTarget, 4642);
R_DEFINE_ERROR_RESULT(Sha256PartitionHashVerificationFailed, 4643); R_DEFINE_ERROR_RESULT(Sha256PartitionHashVerificationFailed, 4643);
R_DEFINE_ERROR_RESULT(PartitionSignatureVerificationFailed, 4644); R_DEFINE_ERROR_RESULT(PartitionSignatureVerificationFailed, 4644);
R_DEFINE_ERROR_RESULT(Sha256PartitionSignatureVerificationFailed, 4645); R_DEFINE_ERROR_RESULT(Sha256PartitionSignatureVerificationFailed, 4645);
R_DEFINE_ERROR_RESULT(InvalidPartitionEntryOffset, 4646); R_DEFINE_ERROR_RESULT(InvalidPartitionEntryOffset, 4646);
R_DEFINE_ERROR_RESULT(InvalidSha256PartitionMetaDataSize, 4647); R_DEFINE_ERROR_RESULT(InvalidSha256PartitionMetaDataSize, 4647);
R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679); R_DEFINE_ERROR_RANGE(BuiltInStorageCorrupted, 4661, 4679);
R_DEFINE_ERROR_RESULT(GptHeaderVerificationFailed, 4662); R_DEFINE_ERROR_RESULT(GptHeaderVerificationFailed, 4662);
R_DEFINE_ERROR_RANGE(FatFileSystemCorrupted, 4681, 4699); R_DEFINE_ERROR_RANGE(FatFileSystemCorrupted, 4681, 4699);
R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719); R_DEFINE_ERROR_RANGE(HostFileSystemCorrupted, 4701, 4719);
R_DEFINE_ERROR_RESULT(HostEntryCorrupted, 4702); R_DEFINE_ERROR_RESULT(HostEntryCorrupted, 4702);
R_DEFINE_ERROR_RESULT(HostFileDataCorrupted, 4703); R_DEFINE_ERROR_RESULT(HostFileDataCorrupted, 4703);
R_DEFINE_ERROR_RESULT(HostFileCorrupted, 4704); R_DEFINE_ERROR_RESULT(HostFileCorrupted, 4704);
R_DEFINE_ERROR_RESULT(InvalidHostHandle, 4705); R_DEFINE_ERROR_RESULT(InvalidHostHandle, 4705);
R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739); R_DEFINE_ERROR_RANGE(DatabaseCorrupted, 4721, 4739);
R_DEFINE_ERROR_RESULT(InvalidAllocationTableBlock, 4722); R_DEFINE_ERROR_RESULT(InvalidAllocationTableBlock, 4722);
R_DEFINE_ERROR_RESULT(InvalidKeyValueListElementIndex, 4723); R_DEFINE_ERROR_RESULT(InvalidKeyValueListElementIndex, 4723);
R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759); R_DEFINE_ERROR_RANGE(AesXtsFileSystemCorrupted, 4741, 4759);
R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769); R_DEFINE_ERROR_RANGE(SaveDataTransferDataCorrupted, 4761, 4769);
R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779); R_DEFINE_ERROR_RANGE(SignedSystemPartitionDataCorrupted, 4771, 4779);
R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781); R_DEFINE_ERROR_RESULT(GameCardLogoDataCorrupted, 4781);
R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999); R_DEFINE_ERROR_RANGE(Unexpected, 5000, 5999);
R_DEFINE_ERROR_RESULT(UnexpectedInAesCtrStorageA, 5315); R_DEFINE_ERROR_RESULT(UnexpectedInAesCtrStorageA, 5315);
R_DEFINE_ERROR_RESULT(UnexpectedInAesXtsStorageA, 5316); R_DEFINE_ERROR_RESULT(UnexpectedInAesXtsStorageA, 5316);
R_DEFINE_ERROR_RESULT(UnexpectedInFindFileSystemA, 5319); R_DEFINE_ERROR_RESULT(UnexpectedInFindFileSystemA, 5319);
R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499); R_DEFINE_ERROR_RANGE(PreconditionViolation, 6000, 6499);
R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199); R_DEFINE_ERROR_RANGE(InvalidArgument, 6001, 6199);
R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029); R_DEFINE_ERROR_RANGE(InvalidPath, 6002, 6029);
R_DEFINE_ERROR_RESULT(TooLongPath, 6003); R_DEFINE_ERROR_RESULT(TooLongPath, 6003);
R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004); R_DEFINE_ERROR_RESULT(InvalidCharacter, 6004);
R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005); R_DEFINE_ERROR_RESULT(InvalidPathFormat, 6005);
R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006); R_DEFINE_ERROR_RESULT(DirectoryUnobtainable, 6006);
R_DEFINE_ERROR_RESULT(NotNormalized, 6007); R_DEFINE_ERROR_RESULT(NotNormalized, 6007);
R_DEFINE_ERROR_RANGE(InvalidPathForOperation, 6030, 6059); R_DEFINE_ERROR_RANGE(InvalidPathForOperation, 6030, 6059);
R_DEFINE_ERROR_RESULT(DirectoryNotDeletable, 6031); R_DEFINE_ERROR_RESULT(DirectoryNotDeletable, 6031);
R_DEFINE_ERROR_RESULT(DirectoryNotRenamable, 6032); R_DEFINE_ERROR_RESULT(DirectoryNotRenamable, 6032);
R_DEFINE_ERROR_RESULT(IncompatiblePath, 6033); R_DEFINE_ERROR_RESULT(IncompatiblePath, 6033);
R_DEFINE_ERROR_RESULT(RenameToOtherFileSystem, 6034); R_DEFINE_ERROR_RESULT(RenameToOtherFileSystem, 6034);
R_DEFINE_ERROR_RESULT(InvalidOffset, 6061); R_DEFINE_ERROR_RESULT(InvalidOffset, 6061);
R_DEFINE_ERROR_RESULT(InvalidSize, 6062); R_DEFINE_ERROR_RESULT(InvalidSize, 6062);
R_DEFINE_ERROR_RESULT(NullptrArgument, 6063); R_DEFINE_ERROR_RESULT(NullptrArgument, 6063);
R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064); R_DEFINE_ERROR_RESULT(InvalidAlignment, 6064);
R_DEFINE_ERROR_RESULT(InvalidMountName, 6065); R_DEFINE_ERROR_RESULT(InvalidMountName, 6065);
R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066); R_DEFINE_ERROR_RESULT(ExtensionSizeTooLarge, 6066);
R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067); R_DEFINE_ERROR_RESULT(ExtensionSizeInvalid, 6067);
R_DEFINE_ERROR_RESULT(InvalidOpenMode, 6072); R_DEFINE_ERROR_RESULT(InvalidOpenMode, 6072);
R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099); R_DEFINE_ERROR_RANGE(InvalidEnumValue, 6080, 6099);
R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081); R_DEFINE_ERROR_RESULT(InvalidSaveDataState, 6081);
R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082); R_DEFINE_ERROR_RESULT(InvalidSaveDataSpaceId, 6082);
R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299); R_DEFINE_ERROR_RANGE(InvalidOperationForOpenMode, 6200, 6299);
R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201); R_DEFINE_ERROR_RESULT(FileExtensionWithoutOpenModeAllowAppend, 6201);
R_DEFINE_ERROR_RESULT(ReadNotPermitted, 6202); R_DEFINE_ERROR_RESULT(ReadNotPermitted, 6202);
R_DEFINE_ERROR_RESULT(WriteNotPermitted, 6203); R_DEFINE_ERROR_RESULT(WriteNotPermitted, 6203);
R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399); R_DEFINE_ERROR_RANGE(UnsupportedOperation, 6300, 6399);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageA, 6302); R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageA, 6302);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageB, 6303); R_DEFINE_ERROR_RESULT(UnsupportedOperationInSubStorageB, 6303);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageA, 6304); R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageA, 6304);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageB, 6305); R_DEFINE_ERROR_RESULT(UnsupportedOperationInMemoryStorageB, 6305);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageA, 6306); R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageA, 6306);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageB, 6307); R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileStorageB, 6307);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInSwitchStorageA, 6308); R_DEFINE_ERROR_RESULT(UnsupportedOperationInSwitchStorageA, 6308);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageA, 6310); R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageA, 6310);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageB, 6311); R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageB, 6311);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageC, 6312); R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrCounterExtendedStorageC, 6312);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalA, 6313); R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalA, 6313);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalB, 6314); R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageExternalB, 6314);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageA, 6315); R_DEFINE_ERROR_RESULT(UnsupportedOperationInAesCtrStorageA, 6315);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageA, 6316); R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageA, 6316);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageB, 6317); R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalIntegrityVerificationStorageB, 6317);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageA, 6318); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageA, 6318);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageB, 6319); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageB, 6319);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageC, 6320); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityVerificationStorageC, 6320);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageA, 6321); R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageA, 6321);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageB, 6322); R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageB, 6322);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageC, 6323); R_DEFINE_ERROR_RESULT(UnsupportedOperationInBlockCacheBufferedStorageC, 6323);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageA, 6324); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageA, 6324);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageB, 6325); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageB, 6325);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageC, 6326); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIndirectStorageC, 6326);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageA, 6327); R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageA, 6327);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageB, 6328); R_DEFINE_ERROR_RESULT(UnsupportedOperationInZeroStorageB, 6328);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalSha256StorageA, 6329); R_DEFINE_ERROR_RESULT(UnsupportedOperationInHierarchicalSha256StorageA, 6329);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageA, 6330); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageA, 6330);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageB, 6331); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyBlockCacheStorageB, 6331);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityRomFsStorageA , 6332); R_DEFINE_ERROR_RESULT(UnsupportedOperationInIntegrityRomFsStorageA , 6332);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileServiceObjectAdapterA, 6362); R_DEFINE_ERROR_RESULT(UnsupportedOperationInFileServiceObjectAdapterA, 6362);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemA, 6364); R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemA, 6364);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemB, 6365); R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemB, 6365);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemC, 6366); R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileSystemC, 6366);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileA, 6367); R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileA, 6367);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileB, 6368); R_DEFINE_ERROR_RESULT(UnsupportedOperationInRomFsFileB, 6368);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateA, 6369); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateA, 6369);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateB, 6370); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateB, 6370);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateC, 6371); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileSystemTemplateC, 6371);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileA, 6372); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileA, 6372);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileB, 6373); R_DEFINE_ERROR_RESULT(UnsupportedOperationInReadOnlyFileB, 6373);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemA, 6374); R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemA, 6374);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemB, 6375); R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileSystemB, 6375);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileA, 6376); R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileA, 6376);
R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileB, 6377); R_DEFINE_ERROR_RESULT(UnsupportedOperationInPartitionFileB, 6377);
R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449); R_DEFINE_ERROR_RANGE(PermissionDenied, 6400, 6449);
R_DEFINE_ERROR_RESULT(NeedFlush, 6454); R_DEFINE_ERROR_RESULT(NeedFlush, 6454);
R_DEFINE_ERROR_RESULT(FileNotClosed, 6455); R_DEFINE_ERROR_RESULT(FileNotClosed, 6455);
R_DEFINE_ERROR_RESULT(DirectoryNotClosed, 6456); R_DEFINE_ERROR_RESULT(DirectoryNotClosed, 6456);
R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457); R_DEFINE_ERROR_RESULT(WriteModeFileNotClosed, 6457);
R_DEFINE_ERROR_RESULT(AllocatorAlreadyRegistered, 6458); R_DEFINE_ERROR_RESULT(AllocatorAlreadyRegistered, 6458);
R_DEFINE_ERROR_RESULT(DefaultAllocatorUsed, 6459); R_DEFINE_ERROR_RESULT(DefaultAllocatorUsed, 6459);
R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461); R_DEFINE_ERROR_RESULT(AllocatorAlignmentViolation, 6461);
R_DEFINE_ERROR_RESULT(UserNotExist, 6465); R_DEFINE_ERROR_RESULT(UserNotExist, 6465);
R_DEFINE_ERROR_RANGE(NotFound, 6600, 6699); R_DEFINE_ERROR_RANGE(NotFound, 6600, 6699);
R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799); R_DEFINE_ERROR_RANGE(OutOfResource, 6700, 6799);
R_DEFINE_ERROR_RESULT(BufferAllocationFailed, 6705); R_DEFINE_ERROR_RESULT(BufferAllocationFailed, 6705);
R_DEFINE_ERROR_RESULT(MappingTableFull, 6706); R_DEFINE_ERROR_RESULT(MappingTableFull, 6706);
R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709); R_DEFINE_ERROR_RESULT(OpenCountLimit, 6709);
R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899); R_DEFINE_ERROR_RANGE(MappingFailed, 6800, 6899);
R_DEFINE_ERROR_RESULT(MapFull, 6811); R_DEFINE_ERROR_RESULT(MapFull, 6811);
R_DEFINE_ERROR_RANGE(BadState, 6900, 6999); R_DEFINE_ERROR_RANGE(BadState, 6900, 6999);
R_DEFINE_ERROR_RESULT(NotInitialized, 6902); R_DEFINE_ERROR_RESULT(NotInitialized, 6902);
R_DEFINE_ERROR_RESULT(NotMounted, 6905); R_DEFINE_ERROR_RESULT(NotMounted, 6905);
R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904); R_DEFINE_ERROR_RANGE(DbmNotFound, 7901, 7904);
R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902); R_DEFINE_ERROR_RESULT(DbmKeyNotFound, 7902);
R_DEFINE_ERROR_RESULT(DbmFileNotFound, 7903); R_DEFINE_ERROR_RESULT(DbmFileNotFound, 7903);
R_DEFINE_ERROR_RESULT(DbmDirectoryNotFound, 7904); R_DEFINE_ERROR_RESULT(DbmDirectoryNotFound, 7904);
R_DEFINE_ERROR_RESULT(DbmAlreadyExists, 7906); R_DEFINE_ERROR_RESULT(DbmAlreadyExists, 7906);
R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907); R_DEFINE_ERROR_RESULT(DbmKeyFull, 7907);
R_DEFINE_ERROR_RESULT(DbmDirectoryEntryFull, 7908); R_DEFINE_ERROR_RESULT(DbmDirectoryEntryFull, 7908);
R_DEFINE_ERROR_RESULT(DbmFileEntryFull, 7909); R_DEFINE_ERROR_RESULT(DbmFileEntryFull, 7909);
R_DEFINE_ERROR_RANGE(DbmFindFinished, 7910, 7912); R_DEFINE_ERROR_RANGE(DbmFindFinished, 7910, 7912);
R_DEFINE_ERROR_RESULT(DbmFindKeyFinished, 7911); R_DEFINE_ERROR_RESULT(DbmFindKeyFinished, 7911);
R_DEFINE_ERROR_RESULT(DbmIterationFinished, 7912); R_DEFINE_ERROR_RESULT(DbmIterationFinished, 7912);
R_DEFINE_ERROR_RESULT(DbmInvalidOperation, 7914); R_DEFINE_ERROR_RESULT(DbmInvalidOperation, 7914);
R_DEFINE_ERROR_RESULT(DbmInvalidPathFormat, 7915); R_DEFINE_ERROR_RESULT(DbmInvalidPathFormat, 7915);
R_DEFINE_ERROR_RESULT(DbmDirectoryNameTooLong, 7916); R_DEFINE_ERROR_RESULT(DbmDirectoryNameTooLong, 7916);
R_DEFINE_ERROR_RESULT(DbmFileNameTooLong, 7917); R_DEFINE_ERROR_RESULT(DbmFileNameTooLong, 7917);
} }

View file

@ -86,6 +86,9 @@ void __appInit(void) {
spl::InitializeForFs(); spl::InitializeForFs();
}); });
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Initialize fssystem library. */ /* Initialize fssystem library. */
fssystem::InitializeForFileSystemProxy(); fssystem::InitializeForFileSystemProxy();

View file

@ -142,6 +142,9 @@ namespace {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(fatal, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(fatal, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(fatal, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(fatal, Main));

View file

@ -115,6 +115,9 @@ namespace {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ldr, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ldr, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ldr, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ldr, Main));

View file

@ -262,6 +262,9 @@ namespace {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ncm, MainWaitThreads)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(ncm, MainWaitThreads));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads));

View file

@ -145,6 +145,9 @@ void __appExit(void) {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* Disable auto-abort in fs operations. */
fs::SetEnabledAutoAbort(false);
/* Set thread name. */ /* Set thread name. */
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pgl, Main)); os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(pgl, Main));
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, Main)); AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, Main));