mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-25 02:50:18 +00:00
strat: always use explicit result namespacing
This commit is contained in:
parent
303c6eb5f9
commit
b0e520112b
29 changed files with 237 additions and 237 deletions
|
@ -69,7 +69,7 @@ namespace ams::kvdb {
|
||||||
|
|
||||||
/* Allocate a buffer. */
|
/* Allocate a buffer. */
|
||||||
this->buffer = new (std::nothrow) u8[size];
|
this->buffer = new (std::nothrow) u8[size];
|
||||||
R_UNLESS(this->buffer != nullptr, ResultAllocationFailed());
|
R_UNLESS(this->buffer != nullptr, kvdb::ResultAllocationFailed());
|
||||||
|
|
||||||
this->size = size;
|
this->size = size;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -219,7 +219,7 @@ namespace ams::kvdb {
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
/* Check that the entry type is correct. */
|
/* Check that the entry type is correct. */
|
||||||
R_UNLESS(entry_type == type, ResultInvalidFilesystemState());
|
R_UNLESS(entry_type == type, kvdb::ResultInvalidFilesystemState());
|
||||||
|
|
||||||
/* The entry exists and is the correct type. */
|
/* The entry exists and is the correct type. */
|
||||||
*out = true;
|
*out = true;
|
||||||
|
@ -249,10 +249,10 @@ namespace ams::kvdb {
|
||||||
R_TRY(DirectoryExists(&has_kvs, GetFileKeyValueStorePath(dir)));
|
R_TRY(DirectoryExists(&has_kvs, GetFileKeyValueStorePath(dir)));
|
||||||
|
|
||||||
/* If neither exists, CreateNewCache was never called. */
|
/* If neither exists, CreateNewCache was never called. */
|
||||||
R_UNLESS(has_lru || has_kvs, ResultNotCreated());
|
R_UNLESS(has_lru || has_kvs, kvdb::ResultNotCreated());
|
||||||
|
|
||||||
/* If one exists but not the other, we have an invalid state. */
|
/* If one exists but not the other, we have an invalid state. */
|
||||||
R_UNLESS(has_lru && has_kvs, ResultInvalidFilesystemState());
|
R_UNLESS(has_lru && has_kvs, kvdb::ResultInvalidFilesystemState());
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace ams::kvdb {
|
||||||
|
|
||||||
Result Initialize(size_t capacity, MemoryResource *mr) {
|
Result Initialize(size_t capacity, MemoryResource *mr) {
|
||||||
this->entries = reinterpret_cast<Entry *>(mr->Allocate(sizeof(Entry) * capacity));
|
this->entries = reinterpret_cast<Entry *>(mr->Allocate(sizeof(Entry) * capacity));
|
||||||
R_UNLESS(this->entries != nullptr, ResultAllocationFailed());
|
R_UNLESS(this->entries != nullptr, kvdb::ResultAllocationFailed());
|
||||||
this->capacity = capacity;
|
this->capacity = capacity;
|
||||||
this->memory_resource = mr;
|
this->memory_resource = mr;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -136,14 +136,14 @@ namespace ams::kvdb {
|
||||||
this->memory_resource->Deallocate(it->GetValuePointer(), it->GetValueSize());
|
this->memory_resource->Deallocate(it->GetValuePointer(), it->GetValueSize());
|
||||||
} else {
|
} else {
|
||||||
/* We need to add a new entry. Check we have room, move future keys forward. */
|
/* We need to add a new entry. Check we have room, move future keys forward. */
|
||||||
R_UNLESS(this->count < this->capacity, ResultOutOfKeyResource());
|
R_UNLESS(this->count < this->capacity, kvdb::ResultOutOfKeyResource());
|
||||||
std::memmove(it + 1, it, sizeof(*it) * (this->end() - it));
|
std::memmove(it + 1, it, sizeof(*it) * (this->end() - it));
|
||||||
this->count++;
|
this->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new value. */
|
/* Allocate new value. */
|
||||||
void *new_value = this->memory_resource->Allocate(value_size);
|
void *new_value = this->memory_resource->Allocate(value_size);
|
||||||
R_UNLESS(new_value != nullptr, ResultAllocationFailed());
|
R_UNLESS(new_value != nullptr, kvdb::ResultAllocationFailed());
|
||||||
std::memcpy(new_value, value, value_size);
|
std::memcpy(new_value, value, value_size);
|
||||||
|
|
||||||
/* Save the new Entry in the map. */
|
/* Save the new Entry in the map. */
|
||||||
|
@ -152,7 +152,7 @@ namespace ams::kvdb {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddUnsafe(const Key &key, void *value, size_t value_size) {
|
Result AddUnsafe(const Key &key, void *value, size_t value_size) {
|
||||||
R_UNLESS(this->count < this->capacity, ResultOutOfKeyResource());
|
R_UNLESS(this->count < this->capacity, kvdb::ResultOutOfKeyResource());
|
||||||
|
|
||||||
this->entries[this->count++] = Entry(key, value, value_size);
|
this->entries[this->count++] = Entry(key, value, value_size);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -161,7 +161,7 @@ namespace ams::kvdb {
|
||||||
Result Remove(const Key &key) {
|
Result Remove(const Key &key) {
|
||||||
/* Find entry for key. */
|
/* Find entry for key. */
|
||||||
Entry *it = this->find(key);
|
Entry *it = this->find(key);
|
||||||
R_UNLESS(it != this->end(), ResultKeyNotFound());
|
R_UNLESS(it != this->end(), kvdb::ResultKeyNotFound());
|
||||||
|
|
||||||
/* Free the value, move entries back. */
|
/* Free the value, move entries back. */
|
||||||
this->memory_resource->Deallocate(it->GetValuePointer(), it->GetValueSize());
|
this->memory_resource->Deallocate(it->GetValuePointer(), it->GetValueSize());
|
||||||
|
@ -324,7 +324,7 @@ namespace ams::kvdb {
|
||||||
|
|
||||||
/* Allocate memory for value. */
|
/* Allocate memory for value. */
|
||||||
void *new_value = this->memory_resource->Allocate(value_size);
|
void *new_value = this->memory_resource->Allocate(value_size);
|
||||||
R_UNLESS(new_value != nullptr, ResultAllocationFailed());
|
R_UNLESS(new_value != nullptr, kvdb::ResultAllocationFailed());
|
||||||
auto value_guard = SCOPE_GUARD { this->memory_resource->Deallocate(new_value, value_size); };
|
auto value_guard = SCOPE_GUARD { this->memory_resource->Deallocate(new_value, value_size); };
|
||||||
|
|
||||||
/* Read key and value. */
|
/* Read key and value. */
|
||||||
|
@ -380,7 +380,7 @@ namespace ams::kvdb {
|
||||||
Result Get(size_t *out_size, void *out_value, size_t max_out_size, const Key &key) {
|
Result Get(size_t *out_size, void *out_value, size_t max_out_size, const Key &key) {
|
||||||
/* Find entry. */
|
/* Find entry. */
|
||||||
auto it = this->find(key);
|
auto it = this->find(key);
|
||||||
R_UNLESS(it != this->end(), ResultKeyNotFound());
|
R_UNLESS(it != this->end(), kvdb::ResultKeyNotFound());
|
||||||
|
|
||||||
size_t size = std::min(max_out_size, it->GetValueSize());
|
size_t size = std::min(max_out_size, it->GetValueSize());
|
||||||
std::memcpy(out_value, it->GetValuePointer(), size);
|
std::memcpy(out_value, it->GetValuePointer(), size);
|
||||||
|
@ -392,7 +392,7 @@ namespace ams::kvdb {
|
||||||
Result GetValuePointer(Value **out_value, const Key &key) {
|
Result GetValuePointer(Value **out_value, const Key &key) {
|
||||||
/* Find entry. */
|
/* Find entry. */
|
||||||
auto it = this->find(key);
|
auto it = this->find(key);
|
||||||
R_UNLESS(it != this->end(), ResultKeyNotFound());
|
R_UNLESS(it != this->end(), kvdb::ResultKeyNotFound());
|
||||||
|
|
||||||
*out_value = it->template GetValuePointer<Value>();
|
*out_value = it->template GetValuePointer<Value>();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -402,7 +402,7 @@ namespace ams::kvdb {
|
||||||
Result GetValuePointer(const Value **out_value, const Key &key) const {
|
Result GetValuePointer(const Value **out_value, const Key &key) const {
|
||||||
/* Find entry. */
|
/* Find entry. */
|
||||||
auto it = this->find(key);
|
auto it = this->find(key);
|
||||||
R_UNLESS(it != this->end(), ResultKeyNotFound());
|
R_UNLESS(it != this->end(), kvdb::ResultKeyNotFound());
|
||||||
|
|
||||||
*out_value = it->template GetValuePointer<Value>();
|
*out_value = it->template GetValuePointer<Value>();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -412,7 +412,7 @@ namespace ams::kvdb {
|
||||||
Result GetValue(Value *out_value, const Key &key) const {
|
Result GetValue(Value *out_value, const Key &key) const {
|
||||||
/* Find entry. */
|
/* Find entry. */
|
||||||
auto it = this->find(key);
|
auto it = this->find(key);
|
||||||
R_UNLESS(it != this->end(), ResultKeyNotFound());
|
R_UNLESS(it != this->end(), kvdb::ResultKeyNotFound());
|
||||||
|
|
||||||
*out_value = it->template GetValue<Value>();
|
*out_value = it->template GetValue<Value>();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -421,7 +421,7 @@ namespace ams::kvdb {
|
||||||
Result GetValueSize(size_t *out_size, const Key &key) const {
|
Result GetValueSize(size_t *out_size, const Key &key) const {
|
||||||
/* Find entry. */
|
/* Find entry. */
|
||||||
auto it = this->find(key);
|
auto it = this->find(key);
|
||||||
R_UNLESS(it != this->end(), ResultKeyNotFound());
|
R_UNLESS(it != this->end(), kvdb::ResultKeyNotFound());
|
||||||
|
|
||||||
*out_size = it->GetValueSize();
|
*out_size = it->GetValueSize();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace ams::ncm {
|
||||||
|
|
||||||
/* Allocate a buffer. */
|
/* Allocate a buffer. */
|
||||||
this->buffer = new (std::nothrow) u8[size];
|
this->buffer = new (std::nothrow) u8[size];
|
||||||
R_UNLESS(this->buffer != nullptr, ResultAllocationFailed());
|
R_UNLESS(this->buffer != nullptr, ncm::ResultAllocationFailed());
|
||||||
|
|
||||||
this->size = size;
|
this->size = size;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace ams::fssrv::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileInterfaceAdapter::Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option) {
|
Result FileInterfaceAdapter::Read(ams::sf::Out<s64> out, s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size, fs::ReadOption option) {
|
||||||
/* TODO: N retries on ResultDataCorrupted, we may want to eventually. */
|
/* TODO: N retries on fs::ResultDataCorrupted, we may want to eventually. */
|
||||||
/* TODO: Deep retry */
|
/* TODO: Deep retry */
|
||||||
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||||
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||||
|
@ -126,7 +126,7 @@ namespace ams::fssrv::impl {
|
||||||
const s64 max_num_entries = out_entries.GetSize() / sizeof(fs::DirectoryEntry);
|
const s64 max_num_entries = out_entries.GetSize() / sizeof(fs::DirectoryEntry);
|
||||||
R_UNLESS(max_num_entries >= 0, fs::ResultInvalidSize());
|
R_UNLESS(max_num_entries >= 0, fs::ResultInvalidSize());
|
||||||
|
|
||||||
/* TODO: N retries on ResultDataCorrupted, we may want to eventually. */
|
/* TODO: N retries on fs::ResultDataCorrupted, we may want to eventually. */
|
||||||
return this->base_dir->Read(out.GetPointer(), reinterpret_cast<fs::DirectoryEntry *>(out_entries.GetPointer()), max_num_entries);
|
return this->base_dir->Read(out.GetPointer(), reinterpret_cast<fs::DirectoryEntry *>(out_entries.GetPointer()), max_num_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ namespace ams::fssrv::impl {
|
||||||
PathNormalizer normalizer(path.str);
|
PathNormalizer normalizer(path.str);
|
||||||
R_UNLESS(normalizer.GetPath() != nullptr, normalizer.GetResult());
|
R_UNLESS(normalizer.GetPath() != nullptr, normalizer.GetResult());
|
||||||
|
|
||||||
/* TODO: N retries on ResultDataCorrupted, we may want to eventually. */
|
/* TODO: N retries on fs::ResultDataCorrupted, we may want to eventually. */
|
||||||
std::unique_ptr<fs::fsa::IFile> file;
|
std::unique_ptr<fs::fsa::IFile> file;
|
||||||
R_TRY(this->base_fs->OpenFile(&file, normalizer.GetPath(), static_cast<fs::OpenMode>(mode)));
|
R_TRY(this->base_fs->OpenFile(&file, normalizer.GetPath(), static_cast<fs::OpenMode>(mode)));
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ namespace ams::fssrv::impl {
|
||||||
PathNormalizer normalizer(path.str);
|
PathNormalizer normalizer(path.str);
|
||||||
R_UNLESS(normalizer.GetPath() != nullptr, normalizer.GetResult());
|
R_UNLESS(normalizer.GetPath() != nullptr, normalizer.GetResult());
|
||||||
|
|
||||||
/* TODO: N retries on ResultDataCorrupted, we may want to eventually. */
|
/* TODO: N retries on fs::ResultDataCorrupted, we may want to eventually. */
|
||||||
std::unique_ptr<fs::fsa::IDirectory> dir;
|
std::unique_ptr<fs::fsa::IDirectory> dir;
|
||||||
R_TRY(this->base_fs->OpenDirectory(&dir, normalizer.GetPath(), static_cast<fs::OpenDirectoryMode>(mode)));
|
R_TRY(this->base_fs->OpenDirectory(&dir, normalizer.GetPath(), static_cast<fs::OpenDirectoryMode>(mode)));
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace ams::fssrv::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result StorageInterfaceAdapter::Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size) {
|
Result StorageInterfaceAdapter::Read(s64 offset, const ams::sf::OutNonSecureBuffer &buffer, s64 size) {
|
||||||
/* TODO: N retries on ResultDataCorrupted, we may want to eventually. */
|
/* TODO: N retries on fs::ResultDataCorrupted, we may want to eventually. */
|
||||||
/* TODO: Deep retry */
|
/* TODO: Deep retry */
|
||||||
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
R_UNLESS(offset >= 0, fs::ResultInvalidOffset());
|
||||||
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
R_UNLESS(size >= 0, fs::ResultInvalidSize());
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace ams::fssystem {
|
||||||
const size_t size = normalized_path_len + 1;
|
const size_t size = normalized_path_len + 1;
|
||||||
char *new_dir = static_cast<char *>(fs::impl::Allocate(size));
|
char *new_dir = static_cast<char *>(fs::impl::Allocate(size));
|
||||||
AMS_ABORT_UNLESS(new_dir != nullptr);
|
AMS_ABORT_UNLESS(new_dir != nullptr);
|
||||||
/* TODO: custom ResultAllocationFailure? */
|
/* TODO: custom fs::ResultAllocationFailure? */
|
||||||
|
|
||||||
/* Copy path in. */
|
/* Copy path in. */
|
||||||
std::memcpy(new_dir, normalized_path, normalized_path_len);
|
std::memcpy(new_dir, normalized_path, normalized_path_len);
|
||||||
|
|
|
@ -133,7 +133,7 @@ namespace ams::fssystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Return a result here? Nintendo does not, but they have other allocation failed results. */
|
/* TODO: Return a result here? Nintendo does not, but they have other allocation failed results. */
|
||||||
/* Consider returning ResultFsAllocationFailureInDirectorySaveDataFileSystem? */
|
/* Consider returning fs::ResultFsAllocationFailureInDirectorySaveDataFileSystem? */
|
||||||
AMS_ABORT_UNLESS(false);
|
AMS_ABORT_UNLESS(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
namespace ams::i2c {
|
namespace ams::i2c {
|
||||||
|
|
||||||
Result CommandListFormatter::IsEnqueueAble(size_t sz) const {
|
Result CommandListFormatter::IsEnqueueAble(size_t sz) const {
|
||||||
R_UNLESS(this->command_list_length - this->current_index >= sz, ResultCommandListFull());
|
R_UNLESS(this->command_list_length - this->current_index >= sz, i2c::ResultCommandListFull());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace ams::kvdb {
|
||||||
u32 entry_count;
|
u32 entry_count;
|
||||||
|
|
||||||
Result Validate() const {
|
Result Validate() const {
|
||||||
R_UNLESS(std::memcmp(this->magic, ArchiveHeaderMagic, sizeof(ArchiveHeaderMagic)) == 0, ResultInvalidKeyValue());
|
R_UNLESS(std::memcmp(this->magic, ArchiveHeaderMagic, sizeof(ArchiveHeaderMagic)) == 0, kvdb::ResultInvalidKeyValue());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace ams::kvdb {
|
||||||
u32 value_size;
|
u32 value_size;
|
||||||
|
|
||||||
Result Validate() const {
|
Result Validate() const {
|
||||||
R_UNLESS(std::memcmp(this->magic, ArchiveEntryMagic, sizeof(ArchiveEntryMagic)) == 0, ResultInvalidKeyValue());
|
R_UNLESS(std::memcmp(this->magic, ArchiveEntryMagic, sizeof(ArchiveEntryMagic)) == 0, kvdb::ResultInvalidKeyValue());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +68,8 @@ namespace ams::kvdb {
|
||||||
/* Reader functionality. */
|
/* Reader functionality. */
|
||||||
Result ArchiveReader::Peek(void *dst, size_t size) {
|
Result ArchiveReader::Peek(void *dst, size_t size) {
|
||||||
/* Bounds check. */
|
/* Bounds check. */
|
||||||
R_UNLESS(this->offset + size <= this->buffer.GetSize(), ResultInvalidKeyValue());
|
R_UNLESS(this->offset + size <= this->buffer.GetSize(), kvdb::ResultInvalidKeyValue());
|
||||||
R_UNLESS(this->offset < this->offset + size, ResultInvalidKeyValue());
|
R_UNLESS(this->offset < this->offset + size, kvdb::ResultInvalidKeyValue());
|
||||||
|
|
||||||
std::memcpy(dst, this->buffer.Get() + this->offset, size);
|
std::memcpy(dst, this->buffer.Get() + this->offset, size);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -129,8 +129,8 @@ namespace ams::kvdb {
|
||||||
/* Writer functionality. */
|
/* Writer functionality. */
|
||||||
Result ArchiveWriter::Write(const void *src, size_t size) {
|
Result ArchiveWriter::Write(const void *src, size_t size) {
|
||||||
/* Bounds check. */
|
/* Bounds check. */
|
||||||
R_UNLESS(this->offset + size <= this->buffer.GetSize(), ResultInvalidKeyValue());
|
R_UNLESS(this->offset + size <= this->buffer.GetSize(), kvdb::ResultInvalidKeyValue());
|
||||||
R_UNLESS(this->offset < this->offset + size, ResultInvalidKeyValue());
|
R_UNLESS(this->offset < this->offset + size, kvdb::ResultInvalidKeyValue());
|
||||||
|
|
||||||
std::memcpy(this->buffer.Get() + this->offset, src, size);
|
std::memcpy(this->buffer.Get() + this->offset, src, size);
|
||||||
this->offset += size;
|
this->offset += size;
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace ams::kvdb {
|
||||||
/* If we have memory to work with, ensure it's at least enough for the cache entries. */
|
/* If we have memory to work with, ensure it's at least enough for the cache entries. */
|
||||||
if (this->backing_buffer != nullptr) {
|
if (this->backing_buffer != nullptr) {
|
||||||
this->entries = static_cast<decltype(this->entries)>(this->Allocate(sizeof(*this->entries) * this->capacity));
|
this->entries = static_cast<decltype(this->entries)>(this->Allocate(sizeof(*this->entries) * this->capacity));
|
||||||
R_UNLESS(this->entries != nullptr, ResultBufferInsufficient());
|
R_UNLESS(this->entries != nullptr, kvdb::ResultBufferInsufficient());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -153,13 +153,13 @@ namespace ams::kvdb {
|
||||||
/* TODO: Nintendo does not validate that the key is valid hex. Should we do this? */
|
/* TODO: Nintendo does not validate that the key is valid hex. Should we do this? */
|
||||||
const size_t file_name_len = file_name.GetLength();
|
const size_t file_name_len = file_name.GetLength();
|
||||||
const size_t key_name_len = file_name_len - FileExtensionLength;
|
const size_t key_name_len = file_name_len - FileExtensionLength;
|
||||||
R_UNLESS(file_name_len >= FileExtensionLength + 2, ResultInvalidKeyValue());
|
R_UNLESS(file_name_len >= FileExtensionLength + 2, kvdb::ResultInvalidKeyValue());
|
||||||
R_UNLESS(file_name.EndsWith(FileExtension), ResultInvalidKeyValue());
|
R_UNLESS(file_name.EndsWith(FileExtension), kvdb::ResultInvalidKeyValue());
|
||||||
R_UNLESS(util::IsAligned(key_name_len, 2), ResultInvalidKeyValue());
|
R_UNLESS(util::IsAligned(key_name_len, 2), kvdb::ResultInvalidKeyValue());
|
||||||
|
|
||||||
/* Validate that we have space for the converted key. */
|
/* Validate that we have space for the converted key. */
|
||||||
const size_t key_size = key_name_len / 2;
|
const size_t key_size = key_name_len / 2;
|
||||||
R_UNLESS(key_size <= max_out_size, ResultBufferInsufficient());
|
R_UNLESS(key_size <= max_out_size, kvdb::ResultBufferInsufficient());
|
||||||
|
|
||||||
/* Convert the hex key back. */
|
/* Convert the hex key back. */
|
||||||
u8 *out_key = static_cast<u8 *>(_out_key);
|
u8 *out_key = static_cast<u8 *>(_out_key);
|
||||||
|
@ -195,7 +195,7 @@ namespace ams::kvdb {
|
||||||
std::scoped_lock lk(this->lock);
|
std::scoped_lock lk(this->lock);
|
||||||
|
|
||||||
/* Ensure key size is small enough. */
|
/* Ensure key size is small enough. */
|
||||||
R_UNLESS(key_size <= MaxKeySize, ResultOutOfKeyResource());
|
R_UNLESS(key_size <= MaxKeySize, kvdb::ResultOutOfKeyResource());
|
||||||
|
|
||||||
/* Try to get from cache. */
|
/* Try to get from cache. */
|
||||||
{
|
{
|
||||||
|
@ -209,7 +209,7 @@ namespace ams::kvdb {
|
||||||
/* Open the value file. */
|
/* Open the value file. */
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
R_TRY_CATCH(fs::OpenFile(std::addressof(file), this->GetPath(key, key_size), fs::OpenMode_Read)) {
|
R_TRY_CATCH(fs::OpenFile(std::addressof(file), this->GetPath(key, key_size), fs::OpenMode_Read)) {
|
||||||
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound());
|
R_CONVERT(fs::ResultPathNotFound, kvdb::ResultKeyNotFound());
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ namespace ams::kvdb {
|
||||||
R_TRY(fs::GetFileSize(std::addressof(file_size), file));
|
R_TRY(fs::GetFileSize(std::addressof(file_size), file));
|
||||||
|
|
||||||
/* Ensure there's enough space for the value. */
|
/* Ensure there's enough space for the value. */
|
||||||
R_UNLESS(file_size <= static_cast<s64>(max_out_size), ResultBufferInsufficient());
|
R_UNLESS(file_size <= static_cast<s64>(max_out_size), kvdb::ResultBufferInsufficient());
|
||||||
|
|
||||||
/* Read the value. */
|
/* Read the value. */
|
||||||
const size_t value_size = static_cast<size_t>(file_size);
|
const size_t value_size = static_cast<size_t>(file_size);
|
||||||
|
@ -234,7 +234,7 @@ namespace ams::kvdb {
|
||||||
std::scoped_lock lk(this->lock);
|
std::scoped_lock lk(this->lock);
|
||||||
|
|
||||||
/* Ensure key size is small enough. */
|
/* Ensure key size is small enough. */
|
||||||
R_UNLESS(key_size <= MaxKeySize, ResultOutOfKeyResource());
|
R_UNLESS(key_size <= MaxKeySize, kvdb::ResultOutOfKeyResource());
|
||||||
|
|
||||||
/* Try to get from cache. */
|
/* Try to get from cache. */
|
||||||
{
|
{
|
||||||
|
@ -248,7 +248,7 @@ namespace ams::kvdb {
|
||||||
/* Open the value file. */
|
/* Open the value file. */
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
R_TRY_CATCH(fs::OpenFile(std::addressof(file), this->GetPath(key, key_size), fs::OpenMode_Read)) {
|
R_TRY_CATCH(fs::OpenFile(std::addressof(file), this->GetPath(key, key_size), fs::OpenMode_Read)) {
|
||||||
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound());
|
R_CONVERT(fs::ResultPathNotFound, kvdb::ResultKeyNotFound());
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ namespace ams::kvdb {
|
||||||
std::scoped_lock lk(this->lock);
|
std::scoped_lock lk(this->lock);
|
||||||
|
|
||||||
/* Ensure key size is small enough. */
|
/* Ensure key size is small enough. */
|
||||||
R_UNLESS(key_size <= MaxKeySize, ResultOutOfKeyResource());
|
R_UNLESS(key_size <= MaxKeySize, kvdb::ResultOutOfKeyResource());
|
||||||
|
|
||||||
/* When the cache contains the key being set, Nintendo invalidates the cache. */
|
/* When the cache contains the key being set, Nintendo invalidates the cache. */
|
||||||
if (this->cache.Contains(key, key_size)) {
|
if (this->cache.Contains(key, key_size)) {
|
||||||
|
@ -293,7 +293,7 @@ namespace ams::kvdb {
|
||||||
std::scoped_lock lk(this->lock);
|
std::scoped_lock lk(this->lock);
|
||||||
|
|
||||||
/* Ensure key size is small enough. */
|
/* Ensure key size is small enough. */
|
||||||
R_UNLESS(key_size <= MaxKeySize, ResultOutOfKeyResource());
|
R_UNLESS(key_size <= MaxKeySize, kvdb::ResultOutOfKeyResource());
|
||||||
|
|
||||||
/* When the cache contains the key being set, Nintendo invalidates the cache. */
|
/* When the cache contains the key being set, Nintendo invalidates the cache. */
|
||||||
if (this->cache.Contains(key, key_size)) {
|
if (this->cache.Contains(key, key_size)) {
|
||||||
|
@ -302,7 +302,7 @@ namespace ams::kvdb {
|
||||||
|
|
||||||
/* Remove the file. */
|
/* Remove the file. */
|
||||||
R_TRY_CATCH(fs::DeleteFile(this->GetPath(key, key_size))) {
|
R_TRY_CATCH(fs::DeleteFile(this->GetPath(key, key_size))) {
|
||||||
R_CONVERT(fs::ResultPathNotFound, ResultKeyNotFound())
|
R_CONVERT(fs::ResultPathNotFound, kvdb::ResultKeyNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -94,21 +94,21 @@ namespace ams::ncm {
|
||||||
|
|
||||||
ALWAYS_INLINE Result GetContentStorageNotActiveResult(StorageId storage_id) {
|
ALWAYS_INLINE Result GetContentStorageNotActiveResult(StorageId storage_id) {
|
||||||
switch (storage_id) {
|
switch (storage_id) {
|
||||||
case StorageId::GameCard: return ResultGameCardContentStorageNotActive();
|
case StorageId::GameCard: return ncm::ResultGameCardContentStorageNotActive();
|
||||||
case StorageId::BuiltInSystem: return ResultBuiltInSystemContentStorageNotActive();
|
case StorageId::BuiltInSystem: return ncm::ResultBuiltInSystemContentStorageNotActive();
|
||||||
case StorageId::BuiltInUser: return ResultBuiltInUserContentStorageNotActive();
|
case StorageId::BuiltInUser: return ncm::ResultBuiltInUserContentStorageNotActive();
|
||||||
case StorageId::SdCard: return ResultSdCardContentStorageNotActive();
|
case StorageId::SdCard: return ncm::ResultSdCardContentStorageNotActive();
|
||||||
default: return ResultUnknownContentStorageNotActive();
|
default: return ncm::ResultUnknownContentStorageNotActive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE Result GetContentMetaDatabaseNotActiveResult(StorageId storage_id) {
|
ALWAYS_INLINE Result GetContentMetaDatabaseNotActiveResult(StorageId storage_id) {
|
||||||
switch (storage_id) {
|
switch (storage_id) {
|
||||||
case StorageId::GameCard: return ResultGameCardContentMetaDatabaseNotActive();
|
case StorageId::GameCard: return ncm::ResultGameCardContentMetaDatabaseNotActive();
|
||||||
case StorageId::BuiltInSystem: return ResultBuiltInSystemContentMetaDatabaseNotActive();
|
case StorageId::BuiltInSystem: return ncm::ResultBuiltInSystemContentMetaDatabaseNotActive();
|
||||||
case StorageId::BuiltInUser: return ResultBuiltInUserContentMetaDatabaseNotActive();
|
case StorageId::BuiltInUser: return ncm::ResultBuiltInUserContentMetaDatabaseNotActive();
|
||||||
case StorageId::SdCard: return ResultSdCardContentMetaDatabaseNotActive();
|
case StorageId::SdCard: return ncm::ResultSdCardContentMetaDatabaseNotActive();
|
||||||
default: return ResultUnknownContentMetaDatabaseNotActive();
|
default: return ncm::ResultUnknownContentMetaDatabaseNotActive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace ams::ncm {
|
||||||
|
|
||||||
Result OnMemoryContentMetaDatabaseImpl::LookupOrphanContent(const sf::OutArray<bool> &out_orphaned, const sf::InArray<ContentId> &content_ids) {
|
Result OnMemoryContentMetaDatabaseImpl::LookupOrphanContent(const sf::OutArray<bool> &out_orphaned, const sf::InArray<ContentId> &content_ids) {
|
||||||
AMS_UNUSED(out_orphaned, content_ids);
|
AMS_UNUSED(out_orphaned, content_ids);
|
||||||
return ResultInvalidContentMetaDatabase();
|
return ncm::ResultInvalidContentMetaDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OnMemoryContentMetaDatabaseImpl::Commit() {
|
Result OnMemoryContentMetaDatabaseImpl::Commit() {
|
||||||
|
|
|
@ -135,14 +135,14 @@ namespace ams::settings::impl {
|
||||||
MapKey &Assign(const char * const chars, s32 count) {
|
MapKey &Assign(const char * const chars, s32 count) {
|
||||||
AMS_ASSERT(chars != nullptr);
|
AMS_ASSERT(chars != nullptr);
|
||||||
AMS_ASSERT(count >= 0);
|
AMS_ASSERT(count >= 0);
|
||||||
|
|
||||||
/* Reset the key. */
|
/* Reset the key. */
|
||||||
this->Reset();
|
this->Reset();
|
||||||
|
|
||||||
/* Update the count and allocate the buffer. */
|
/* Update the count and allocate the buffer. */
|
||||||
m_count = count + 1;
|
m_count = count + 1;
|
||||||
m_chars = static_cast<char *>(AllocateFromHeap(m_count));
|
m_chars = static_cast<char *>(AllocateFromHeap(m_count));
|
||||||
|
|
||||||
/* Copy the characters to the buffer. */
|
/* Copy the characters to the buffer. */
|
||||||
std::memcpy(m_chars, chars, count);
|
std::memcpy(m_chars, chars, count);
|
||||||
m_chars[count] = '\x00';
|
m_chars[count] = '\x00';
|
||||||
|
@ -177,7 +177,7 @@ namespace ams::settings::impl {
|
||||||
MapKey MakeMapKey(const SettingsName &name, const SettingsItemKey &item_key) {
|
MapKey MakeMapKey(const SettingsName &name, const SettingsItemKey &item_key) {
|
||||||
/* Create a map key. */
|
/* Create a map key. */
|
||||||
MapKey key(name.value, util::Strnlen(name.value, util::size(name.value)));
|
MapKey key(name.value, util::Strnlen(name.value, util::size(name.value)));
|
||||||
|
|
||||||
/* Append the settings name separator followed by the item key. */
|
/* Append the settings name separator followed by the item key. */
|
||||||
key.Append(SettingsNameSeparator);
|
key.Append(SettingsNameSeparator);
|
||||||
key.Append(item_key.value, util::Strnlen(item_key.value, util::size(item_key.value)));
|
key.Append(item_key.value, util::Strnlen(item_key.value, util::size(item_key.value)));
|
||||||
|
@ -205,10 +205,10 @@ namespace ams::settings::impl {
|
||||||
public:
|
public:
|
||||||
Allocator() noexcept = default;
|
Allocator() noexcept = default;
|
||||||
~Allocator() noexcept = default;
|
~Allocator() noexcept = default;
|
||||||
|
|
||||||
Allocator(const Allocator &) noexcept = default;
|
Allocator(const Allocator &) noexcept = default;
|
||||||
Allocator(Allocator &&) noexcept = default;
|
Allocator(Allocator &&) noexcept = default;
|
||||||
|
|
||||||
T *allocate(size_t n) noexcept {
|
T *allocate(size_t n) noexcept {
|
||||||
return static_cast<T *>(AllocateFromHeap(sizeof(T) * n));
|
return static_cast<T *>(AllocateFromHeap(sizeof(T) * n));
|
||||||
}
|
}
|
||||||
|
@ -222,14 +222,14 @@ namespace ams::settings::impl {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, class U>
|
template<class T, class U>
|
||||||
constexpr inline bool operator==(const Allocator<T> &, const Allocator<U> &) {
|
constexpr inline bool operator==(const Allocator<T> &, const Allocator<U> &) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline size_t MapKeyBufferSize = MapKey::MaxKeySize * 2;
|
constexpr inline size_t MapKeyBufferSize = MapKey::MaxKeySize * 2;
|
||||||
constexpr inline size_t MapEntryBufferSize = 0x40 + sizeof(Map::value_type);
|
constexpr inline size_t MapEntryBufferSize = 0x40 + sizeof(Map::value_type);
|
||||||
|
|
||||||
constexpr inline size_t HeapMemorySize = 512_KB;
|
constexpr inline size_t HeapMemorySize = 512_KB;
|
||||||
|
|
||||||
constinit os::SdkMutex g_key_value_store_mutex;
|
constinit os::SdkMutex g_key_value_store_mutex;
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ namespace ams::settings::impl {
|
||||||
if (lhs_size == 0) {
|
if (lhs_size == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare the two values if they are non-null. */
|
/* Compare the two values if they are non-null. */
|
||||||
return lhs != nullptr && rhs != nullptr && std::memcmp(lhs, rhs, lhs_size) == 0;
|
return lhs != nullptr && rhs != nullptr && std::memcmp(lhs, rhs, lhs_size) == 0;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,7 @@ namespace ams::settings::impl {
|
||||||
/* If the default value size is > 0, copy it to the map value. */
|
/* If the default value size is > 0, copy it to the map value. */
|
||||||
if (map_value.default_value_size > 0) {
|
if (map_value.default_value_size > 0) {
|
||||||
/* Allocate the default value if there is sufficient memory available. */
|
/* Allocate the default value if there is sufficient memory available. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= map_value.default_value_size, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= map_value.default_value_size, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
map_value.default_value = AllocateFromHeap(map_value.default_value_size);
|
map_value.default_value = AllocateFromHeap(map_value.default_value_size);
|
||||||
AMS_ASSERT(map_value.default_value != nullptr);
|
AMS_ASSERT(map_value.default_value != nullptr);
|
||||||
|
|
||||||
|
@ -389,14 +389,14 @@ namespace ams::settings::impl {
|
||||||
map_value.current_value = map_value.default_value;
|
map_value.current_value = map_value.default_value;
|
||||||
} else if (map_value.current_value_size > 0) {
|
} else if (map_value.current_value_size > 0) {
|
||||||
/* Allocate the current value if there is sufficient memory available. */
|
/* Allocate the current value if there is sufficient memory available. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= map_value.current_value_size, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= map_value.current_value_size, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
map_value.current_value = AllocateFromHeap(map_value.current_value_size);
|
map_value.current_value = AllocateFromHeap(map_value.current_value_size);
|
||||||
AMS_ASSERT(map_value.current_value != nullptr);
|
AMS_ASSERT(map_value.current_value != nullptr);
|
||||||
|
|
||||||
/* Copy the current value from the item. */
|
/* Copy the current value from the item. */
|
||||||
std::memcpy(map_value.current_value, item.current_value, map_value.current_value_size);
|
std::memcpy(map_value.current_value, item.current_value, map_value.current_value_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the output map value. */
|
/* Set the output map value. */
|
||||||
*out = map_value;
|
*out = map_value;
|
||||||
|
|
||||||
|
@ -408,12 +408,12 @@ namespace ams::settings::impl {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const char *GetSystemDataMountName();
|
const char *GetSystemDataMountName();
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
const char *GetSystemDataMountName<SystemDataTag::Fwdbg>() {
|
const char *GetSystemDataMountName<SystemDataTag::Fwdbg>() {
|
||||||
return FwdbgSystemDataMountName;
|
return FwdbgSystemDataMountName;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
const char *GetSystemDataMountName<SystemDataTag::PfCfg>() {
|
const char *GetSystemDataMountName<SystemDataTag::PfCfg>() {
|
||||||
return PfCfgSystemDataMountName;
|
return PfCfgSystemDataMountName;
|
||||||
|
@ -423,7 +423,7 @@ namespace ams::settings::impl {
|
||||||
Result GetSystemData(SystemData **out_data, ncm::SystemDataId id) {
|
Result GetSystemData(SystemData **out_data, ncm::SystemDataId id) {
|
||||||
/* Check pre-conditions. */
|
/* Check pre-conditions. */
|
||||||
AMS_ASSERT(out_data != nullptr);
|
AMS_ASSERT(out_data != nullptr);
|
||||||
|
|
||||||
/* Declare static instance variables. */
|
/* Declare static instance variables. */
|
||||||
static constinit util::TypedStorage<SystemData> s_storage = {};
|
static constinit util::TypedStorage<SystemData> s_storage = {};
|
||||||
static constinit bool s_initialized = false;
|
static constinit bool s_initialized = false;
|
||||||
|
@ -512,7 +512,7 @@ namespace ams::settings::impl {
|
||||||
SystemData *system_data = nullptr;
|
SystemData *system_data = nullptr;
|
||||||
R_TRY(GetSystemData<SystemDataTag::Fwdbg>(std::addressof(system_data), ncm::SystemDataId::FirmwareDebugSettings));
|
R_TRY(GetSystemData<SystemDataTag::Fwdbg>(std::addressof(system_data), ncm::SystemDataId::FirmwareDebugSettings));
|
||||||
AMS_ASSERT(system_data != nullptr);
|
AMS_ASSERT(system_data != nullptr);
|
||||||
|
|
||||||
/* Load the default keys/values for the firmware debug system data. */
|
/* Load the default keys/values for the firmware debug system data. */
|
||||||
R_TRY(LoadKeyValueStoreMapDefault(out, *system_data));
|
R_TRY(LoadKeyValueStoreMapDefault(out, *system_data));
|
||||||
|
|
||||||
|
@ -548,10 +548,10 @@ namespace ams::settings::impl {
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoadKeyValueStoreMap(Map *out, SplHardwareType hardware_type) {
|
Result LoadKeyValueStoreMap(Map *out, SplHardwareType hardware_type) {
|
||||||
SystemData *data = nullptr;
|
SystemData *data = nullptr;
|
||||||
|
|
||||||
/* Get the platform configuration system data for the hardware type. */
|
/* Get the platform configuration system data for the hardware type. */
|
||||||
switch (hardware_type) {
|
switch (hardware_type) {
|
||||||
case SplHardwareType_None:
|
case SplHardwareType_None:
|
||||||
|
@ -604,8 +604,8 @@ namespace ams::settings::impl {
|
||||||
|
|
||||||
if (current_value_size > 0) {
|
if (current_value_size > 0) {
|
||||||
/* Ensure there is sufficient memory for the value. */
|
/* Ensure there is sufficient memory for the value. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= current_value_size, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= current_value_size, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
|
|
||||||
/* Allocate the value buffer. */
|
/* Allocate the value buffer. */
|
||||||
current_value_buffer = AllocateFromHeap(current_value_size);
|
current_value_buffer = AllocateFromHeap(current_value_size);
|
||||||
AMS_ASSERT(current_value_buffer != nullptr);
|
AMS_ASSERT(current_value_buffer != nullptr);
|
||||||
|
@ -642,22 +642,22 @@ namespace ams::settings::impl {
|
||||||
/* Load the map entries. */
|
/* Load the map entries. */
|
||||||
R_TRY(LoadKeyValueStoreMapEntries(out, data, [](Map &map, const MapKey &key, u8 type, const void *value_buffer, u32 value_size) -> Result {
|
R_TRY(LoadKeyValueStoreMapEntries(out, data, [](Map &map, const MapKey &key, u8 type, const void *value_buffer, u32 value_size) -> Result {
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Copy the map key. */
|
/* Copy the map key. */
|
||||||
MapKey default_key = key;
|
MapKey default_key = key;
|
||||||
void *default_value_buffer = nullptr;
|
void *default_value_buffer = nullptr;
|
||||||
|
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
/* Free the value buffer if allocated. */
|
/* Free the value buffer if allocated. */
|
||||||
if (default_value_buffer != nullptr) {
|
if (default_value_buffer != nullptr) {
|
||||||
FreeToHeap(default_value_buffer, value_size);
|
FreeToHeap(default_value_buffer, value_size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (value_size > 0) {
|
if (value_size > 0) {
|
||||||
/* Ensure there is sufficient memory for the value. */
|
/* Ensure there is sufficient memory for the value. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= value_size, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= value_size, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
|
|
||||||
/* Allocate the value buffer. */
|
/* Allocate the value buffer. */
|
||||||
default_value_buffer = AllocateFromHeap(value_size);
|
default_value_buffer = AllocateFromHeap(value_size);
|
||||||
|
@ -669,16 +669,16 @@ namespace ams::settings::impl {
|
||||||
|
|
||||||
/* Create the map value. */
|
/* Create the map value. */
|
||||||
MapValue default_value {
|
MapValue default_value {
|
||||||
.type = type,
|
.type = type,
|
||||||
.current_value_size = value_size,
|
.current_value_size = value_size,
|
||||||
.default_value_size = value_size,
|
.default_value_size = value_size,
|
||||||
.current_value = default_value_buffer,
|
.current_value = default_value_buffer,
|
||||||
.default_value = default_value_buffer,
|
.default_value = default_value_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for the value. */
|
/* Ensure there is sufficient memory for the value. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapEntryBufferSize, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapEntryBufferSize, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
|
|
||||||
/* Insert the value into the map. */
|
/* Insert the value into the map. */
|
||||||
map[std::move(default_key)] = default_value;
|
map[std::move(default_key)] = default_value;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -697,7 +697,7 @@ namespace ams::settings::impl {
|
||||||
s64 offset = 0;
|
s64 offset = 0;
|
||||||
u32 total_size = 0;
|
u32 total_size = 0;
|
||||||
R_TRY(ReadData(data, offset, std::addressof(total_size), sizeof(total_size)));
|
R_TRY(ReadData(data, offset, std::addressof(total_size), sizeof(total_size)));
|
||||||
|
|
||||||
/* Iterate through all entries. NOTE: The offset is updated within LoadKeyValueStoreMapEntry. */
|
/* Iterate through all entries. NOTE: The offset is updated within LoadKeyValueStoreMapEntry. */
|
||||||
while (offset < total_size) {
|
while (offset < total_size) {
|
||||||
R_TRY(LoadKeyValueStoreMapEntry(out, data, offset, load));
|
R_TRY(LoadKeyValueStoreMapEntry(out, data, offset, load));
|
||||||
|
@ -718,8 +718,8 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(key_size > 1);
|
AMS_ASSERT(key_size > 1);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for this key. */
|
/* Ensure there is sufficient memory for this key. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= key_size, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= key_size, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Read the key. */
|
/* Read the key. */
|
||||||
void *key_buffer = nullptr;
|
void *key_buffer = nullptr;
|
||||||
R_TRY(ReadDataToHeap(data, offset, std::addressof(key_buffer), key_size));
|
R_TRY(ReadDataToHeap(data, offset, std::addressof(key_buffer), key_size));
|
||||||
|
@ -727,7 +727,7 @@ namespace ams::settings::impl {
|
||||||
ON_SCOPE_EXIT { FreeToHeap(key_buffer, key_size); };
|
ON_SCOPE_EXIT { FreeToHeap(key_buffer, key_size); };
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
const MapKey key(static_cast<const char *>(key_buffer), key_size - 1);
|
const MapKey key(static_cast<const char *>(key_buffer), key_size - 1);
|
||||||
|
|
||||||
|
@ -740,15 +740,15 @@ namespace ams::settings::impl {
|
||||||
R_TRY(ReadData(data, offset, std::addressof(value_size), sizeof(value_size)));
|
R_TRY(ReadData(data, offset, std::addressof(value_size), sizeof(value_size)));
|
||||||
|
|
||||||
void *value_buffer = nullptr;
|
void *value_buffer = nullptr;
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
if (value_buffer != nullptr) {
|
if (value_buffer != nullptr) {
|
||||||
FreeToHeap(value_buffer, value_size);
|
FreeToHeap(value_buffer, value_size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (value_size > 0) {
|
if (value_size > 0) {
|
||||||
/* Ensure there is sufficient memory for the value. */
|
/* Ensure there is sufficient memory for the value. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= value_size, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= value_size, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
|
|
||||||
/* Read the value to the buffer. */
|
/* Read the value to the buffer. */
|
||||||
R_TRY(ReadDataToHeap(data, offset, std::addressof(value_buffer), value_size));
|
R_TRY(ReadDataToHeap(data, offset, std::addressof(value_buffer), value_size));
|
||||||
|
@ -778,14 +778,14 @@ namespace ams::settings::impl {
|
||||||
R_TRY(LoadKeyValueStoreMapCurrent(out, *system_save_data));
|
R_TRY(LoadKeyValueStoreMapCurrent(out, *system_save_data));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Result ReadData(T &data, s64 &offset, void *buffer, size_t size) {
|
Result ReadData(T &data, s64 &offset, void *buffer, size_t size) {
|
||||||
AMS_ASSERT(buffer != nullptr);
|
AMS_ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
/* Read the data. */
|
/* Read the data. */
|
||||||
R_TRY(data.Read(offset, buffer, size));
|
R_TRY(data.Read(offset, buffer, size));
|
||||||
|
|
||||||
/* Increment the offset. */
|
/* Increment the offset. */
|
||||||
offset += static_cast<s64>(size);
|
offset += static_cast<s64>(size);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -800,13 +800,13 @@ namespace ams::settings::impl {
|
||||||
/* Allocate a buffer from the heap. */
|
/* Allocate a buffer from the heap. */
|
||||||
*buffer = AllocateFromHeap(size);
|
*buffer = AllocateFromHeap(size);
|
||||||
AMS_ASSERT(*buffer != nullptr);
|
AMS_ASSERT(*buffer != nullptr);
|
||||||
|
|
||||||
/* Ensure we free the buffer if we fail. */
|
/* Ensure we free the buffer if we fail. */
|
||||||
auto alloc_guard = SCOPE_GUARD { FreeToHeap(*buffer, size); *buffer = nullptr; };
|
auto alloc_guard = SCOPE_GUARD { FreeToHeap(*buffer, size); *buffer = nullptr; };
|
||||||
|
|
||||||
/* Read data to the buffer. */
|
/* Read data to the buffer. */
|
||||||
R_TRY(ReadData(data, offset, *buffer, size));
|
R_TRY(ReadData(data, offset, *buffer, size));
|
||||||
|
|
||||||
/* We succeeded. */
|
/* We succeeded. */
|
||||||
alloc_guard.Cancel();
|
alloc_guard.Cancel();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -909,7 +909,7 @@ namespace ams::settings::impl {
|
||||||
/* Check preconditions. */
|
/* Check preconditions. */
|
||||||
AMS_ASSERT(out_count != nullptr);
|
AMS_ASSERT(out_count != nullptr);
|
||||||
AMS_ASSERT(out_buffer);
|
AMS_ASSERT(out_buffer);
|
||||||
|
|
||||||
/* Attempt to get the system save data. */
|
/* Attempt to get the system save data. */
|
||||||
SystemSaveData *system_save_data = nullptr;
|
SystemSaveData *system_save_data = nullptr;
|
||||||
if (R_SUCCEEDED(GetSystemSaveData(std::addressof(system_save_data), false))) {
|
if (R_SUCCEEDED(GetSystemSaveData(std::addressof(system_save_data), false))) {
|
||||||
|
@ -951,7 +951,7 @@ namespace ams::settings::impl {
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
/* Flush and close the save data. NOTE: Nintendo only does this if SetFileSize succeeds. */
|
/* Flush and close the save data. NOTE: Nintendo only does this if SetFileSize succeeds. */
|
||||||
R_ABORT_UNLESS(data.Flush());
|
R_ABORT_UNLESS(data.Flush());
|
||||||
data.Close();
|
data.Close();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Set the file size of the save data. */
|
/* Set the file size of the save data. */
|
||||||
|
@ -970,7 +970,7 @@ namespace ams::settings::impl {
|
||||||
u8 type = 0;
|
u8 type = 0;
|
||||||
const void *value_buffer = nullptr;
|
const void *value_buffer = nullptr;
|
||||||
u32 value_size = 0;
|
u32 value_size = 0;
|
||||||
|
|
||||||
/* Test if the map value varies from the default. */
|
/* Test if the map value varies from the default. */
|
||||||
if (test(std::addressof(type), std::addressof(value_buffer), std::addressof(value_size), kv_pair.second)) {
|
if (test(std::addressof(type), std::addressof(value_buffer), std::addressof(value_size), kv_pair.second)) {
|
||||||
R_TRY(SaveKeyValueStoreMapEntry(data, current_offset, kv_pair.first, type, value_buffer, value_size));
|
R_TRY(SaveKeyValueStoreMapEntry(data, current_offset, kv_pair.first, type, value_buffer, value_size));
|
||||||
|
@ -1075,7 +1075,7 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(map != nullptr);
|
AMS_ASSERT(map != nullptr);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Create a map key from the key value store's name. */
|
/* Create a map key from the key value store's name. */
|
||||||
MapKey map_key_header(m_name.value);
|
MapKey map_key_header(m_name.value);
|
||||||
|
@ -1089,7 +1089,7 @@ namespace ams::settings::impl {
|
||||||
/* Find an item map key with the name as a prefix. */
|
/* Find an item map key with the name as a prefix. */
|
||||||
for (const auto &kv_pair : *map) {
|
for (const auto &kv_pair : *map) {
|
||||||
const MapKey &map_key = kv_pair.first;
|
const MapKey &map_key = kv_pair.first;
|
||||||
|
|
||||||
/* Check if the name map key is smaller than the current map key, and the current map key contains the name map key. */
|
/* Check if the name map key is smaller than the current map key, and the current map key contains the name map key. */
|
||||||
if (map_key_header < map_key && map_key.Find(map_key_header)) {
|
if (map_key_header < map_key && map_key.Find(map_key_header)) {
|
||||||
item_map_key = std::addressof(map_key);
|
item_map_key = std::addressof(map_key);
|
||||||
|
@ -1098,12 +1098,12 @@ namespace ams::settings::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure we have located an item map key. */
|
/* Ensure we have located an item map key. */
|
||||||
R_UNLESS(item_map_key != nullptr, ResultSettingsItemNotFound());
|
R_UNLESS(item_map_key != nullptr, settings::ResultSettingsItemNotFound());
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for the item map key. */
|
/* Ensure there is sufficient memory for the item map key. */
|
||||||
const size_t item_map_key_size = item_map_key->GetCount() + 1;
|
const size_t item_map_key_size = item_map_key->GetCount() + 1;
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= item_map_key_size, ResultSettingsItemKeyIteratorAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= item_map_key_size, settings::ResultSettingsItemKeyIteratorAllocationFailed());
|
||||||
|
|
||||||
/* Allocate the key buffer. */
|
/* Allocate the key buffer. */
|
||||||
char *buffer = static_cast<char *>(AllocateFromHeap(item_map_key_size));
|
char *buffer = static_cast<char *>(AllocateFromHeap(item_map_key_size));
|
||||||
AMS_ASSERT(buffer != nullptr);
|
AMS_ASSERT(buffer != nullptr);
|
||||||
|
@ -1134,11 +1134,11 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(map != nullptr);
|
AMS_ASSERT(map != nullptr);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Find the key in the map. */
|
/* Find the key in the map. */
|
||||||
const Map::const_iterator it = map->find(MakeMapKey(m_name, item_key));
|
const Map::const_iterator it = map->find(MakeMapKey(m_name, item_key));
|
||||||
R_UNLESS(it != map->end(), ResultSettingsItemNotFound());
|
R_UNLESS(it != map->end(), settings::ResultSettingsItemNotFound());
|
||||||
|
|
||||||
/* Get the map value from the iterator. */
|
/* Get the map value from the iterator. */
|
||||||
const MapValue &map_value = it->second;
|
const MapValue &map_value = it->second;
|
||||||
|
@ -1170,11 +1170,11 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(map != nullptr);
|
AMS_ASSERT(map != nullptr);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Find the key in the map. */
|
/* Find the key in the map. */
|
||||||
const Map::const_iterator it = map->find(MakeMapKey(m_name, item_key));
|
const Map::const_iterator it = map->find(MakeMapKey(m_name, item_key));
|
||||||
R_UNLESS(it != map->end(), ResultSettingsItemNotFound());
|
R_UNLESS(it != map->end(), settings::ResultSettingsItemNotFound());
|
||||||
|
|
||||||
/* Output the value size. */
|
/* Output the value size. */
|
||||||
*out_value_size = it->second.current_value_size;
|
*out_value_size = it->second.current_value_size;
|
||||||
|
@ -1191,11 +1191,11 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(map != nullptr);
|
AMS_ASSERT(map != nullptr);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Find the key in the map. */
|
/* Find the key in the map. */
|
||||||
const Map::iterator it = map->find(MakeMapKey(m_name, item_key));
|
const Map::iterator it = map->find(MakeMapKey(m_name, item_key));
|
||||||
R_UNLESS(it != map->end(), ResultSettingsItemNotFound());
|
R_UNLESS(it != map->end(), settings::ResultSettingsItemNotFound());
|
||||||
|
|
||||||
/* Get the map value from the iterator. */
|
/* Get the map value from the iterator. */
|
||||||
MapValue &map_value = it->second;
|
MapValue &map_value = it->second;
|
||||||
|
@ -1233,7 +1233,7 @@ namespace ams::settings::impl {
|
||||||
Result KeyValueStore::SetValue(const SettingsItemKey &item_key, const void *buffer, size_t buffer_size) {
|
Result KeyValueStore::SetValue(const SettingsItemKey &item_key, const void *buffer, size_t buffer_size) {
|
||||||
/* Check preconditions. */
|
/* Check preconditions. */
|
||||||
AMS_ASSERT(buffer != nullptr);
|
AMS_ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
/* Acquire exclusive access to global state. */
|
/* Acquire exclusive access to global state. */
|
||||||
std::scoped_lock lk(g_key_value_store_mutex);
|
std::scoped_lock lk(g_key_value_store_mutex);
|
||||||
|
|
||||||
|
@ -1243,18 +1243,18 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(map != nullptr);
|
AMS_ASSERT(map != nullptr);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Find the key in the map. */
|
/* Find the key in the map. */
|
||||||
const Map::iterator it = map->find(MakeMapKey(m_name, item_key));
|
const Map::iterator it = map->find(MakeMapKey(m_name, item_key));
|
||||||
R_UNLESS(it != map->end(), ResultSettingsItemNotFound());
|
R_UNLESS(it != map->end(), settings::ResultSettingsItemNotFound());
|
||||||
|
|
||||||
/* Get the map value from the iterator. */
|
/* Get the map value from the iterator. */
|
||||||
MapValue &map_value = it->second;
|
MapValue &map_value = it->second;
|
||||||
|
|
||||||
/* Succeed if the map value is already set to the new value. */
|
/* Succeed if the map value is already set to the new value. */
|
||||||
R_SUCCEED_IF(CompareValue(map_value.current_value, map_value.current_value_size, buffer, buffer_size));
|
R_SUCCEED_IF(CompareValue(map_value.current_value, map_value.current_value_size, buffer, buffer_size));
|
||||||
|
|
||||||
/* Define the value buffer and size variables. */
|
/* Define the value buffer and size variables. */
|
||||||
size_t value_size = buffer_size;
|
size_t value_size = buffer_size;
|
||||||
void *value_buffer = nullptr;
|
void *value_buffer = nullptr;
|
||||||
|
@ -1264,7 +1264,7 @@ namespace ams::settings::impl {
|
||||||
value_buffer = map_value.default_value;
|
value_buffer = map_value.default_value;
|
||||||
} else if (buffer_size > 0) {
|
} else if (buffer_size > 0) {
|
||||||
/* Allocate the new value if there is sufficient memory available. */
|
/* Allocate the new value if there is sufficient memory available. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= value_size, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= value_size, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
value_buffer = AllocateFromHeap(value_size);
|
value_buffer = AllocateFromHeap(value_size);
|
||||||
AMS_ASSERT(value_buffer != nullptr);
|
AMS_ASSERT(value_buffer != nullptr);
|
||||||
|
|
||||||
|
@ -1302,7 +1302,7 @@ namespace ams::settings::impl {
|
||||||
Result AddKeyValueStoreItemForDebug(const KeyValueStoreItemForDebug * const items, size_t items_count) {
|
Result AddKeyValueStoreItemForDebug(const KeyValueStoreItemForDebug * const items, size_t items_count) {
|
||||||
/* Check preconditions. */
|
/* Check preconditions. */
|
||||||
AMS_ASSERT(items != nullptr);
|
AMS_ASSERT(items != nullptr);
|
||||||
|
|
||||||
/* Acquire exclusive access to global state. */
|
/* Acquire exclusive access to global state. */
|
||||||
std::scoped_lock lk(g_key_value_store_mutex);
|
std::scoped_lock lk(g_key_value_store_mutex);
|
||||||
|
|
||||||
|
@ -1323,7 +1323,7 @@ namespace ams::settings::impl {
|
||||||
R_TRY(GetMapValueOfKeyValueStoreItemForDebug(std::addressof(map_value), item));
|
R_TRY(GetMapValueOfKeyValueStoreItemForDebug(std::addressof(map_value), item));
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Create the map key. */
|
/* Create the map key. */
|
||||||
MapKey map_key(item.key);
|
MapKey map_key(item.key);
|
||||||
|
@ -1337,8 +1337,8 @@ namespace ams::settings::impl {
|
||||||
it->second = map_value;
|
it->second = map_value;
|
||||||
} else {
|
} else {
|
||||||
/* Ensure there is sufficient memory for the value. */
|
/* Ensure there is sufficient memory for the value. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapEntryBufferSize, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapEntryBufferSize, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
|
|
||||||
/* Assign the map value to the map key in the map. */
|
/* Assign the map value to the map key in the map. */
|
||||||
(*map)[std::move(map_key)] = map_value;
|
(*map)[std::move(map_key)] = map_value;
|
||||||
}
|
}
|
||||||
|
@ -1367,24 +1367,24 @@ namespace ams::settings::impl {
|
||||||
AMS_ASSERT(map != nullptr);
|
AMS_ASSERT(map != nullptr);
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for two keys. */
|
/* Ensure there is sufficient memory for two keys. */
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, ResultSettingsItemKeyAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= MapKeyBufferSize, settings::ResultSettingsItemKeyAllocationFailed());
|
||||||
|
|
||||||
/* Locate the iterator's current key. */
|
/* Locate the iterator's current key. */
|
||||||
Map::const_iterator it = map->find(MapKey(out->map_key, static_cast<s32>(out->entire_size) - 1));
|
Map::const_iterator it = map->find(MapKey(out->map_key, static_cast<s32>(out->entire_size) - 1));
|
||||||
R_UNLESS(it != map->end(), ResultNotFoundSettingsItemKeyIterator());
|
R_UNLESS(it != map->end(), settings::ResultNotFoundSettingsItemKeyIterator());
|
||||||
|
|
||||||
/* Increment the iterator, ensuring we aren't at the end of the map. */
|
/* Increment the iterator, ensuring we aren't at the end of the map. */
|
||||||
R_UNLESS((++it) != map->end(), ResultStopIteration());
|
R_UNLESS((++it) != map->end(), settings::ResultStopIteration());
|
||||||
|
|
||||||
/* Get the map key. */
|
/* Get the map key. */
|
||||||
const MapKey &map_key = it->first;
|
const MapKey &map_key = it->first;
|
||||||
|
|
||||||
/* Ensure the advanced iterator retains the required name. */
|
/* Ensure the advanced iterator retains the required name. */
|
||||||
R_UNLESS(std::strncmp(map_key.GetString(), out->map_key, out->header_size) == 0, ResultStopIteration());
|
R_UNLESS(std::strncmp(map_key.GetString(), out->map_key, out->header_size) == 0, settings::ResultStopIteration());
|
||||||
|
|
||||||
/* Ensure there is sufficient memory for the map key. */
|
/* Ensure there is sufficient memory for the map key. */
|
||||||
const size_t map_key_size = map_key.GetCount() + 1;
|
const size_t map_key_size = map_key.GetCount() + 1;
|
||||||
R_UNLESS(GetHeapAllocatableSize() >= map_key_size, ResultSettingsItemKeyIteratorAllocationFailed());
|
R_UNLESS(GetHeapAllocatableSize() >= map_key_size, settings::ResultSettingsItemKeyIteratorAllocationFailed());
|
||||||
|
|
||||||
/* Free the iterator's old map key. */
|
/* Free the iterator's old map key. */
|
||||||
FreeToHeap(out->map_key, out->entire_size);
|
FreeToHeap(out->map_key, out->entire_size);
|
||||||
|
@ -1402,7 +1402,7 @@ namespace ams::settings::impl {
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DestroyKeyValueStoreKeyIterator(KeyValueStoreKeyIterator *out) {
|
Result DestroyKeyValueStoreKeyIterator(KeyValueStoreKeyIterator *out) {
|
||||||
/* Check preconditions. */
|
/* Check preconditions. */
|
||||||
AMS_ASSERT(out != nullptr);
|
AMS_ASSERT(out != nullptr);
|
||||||
|
@ -1439,7 +1439,7 @@ namespace ams::settings::impl {
|
||||||
*out_count = map->size();
|
*out_count = map->size();
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetKeyValueStoreItemForDebug(u64 *out_count, KeyValueStoreItemForDebug * const out_items, size_t out_items_count) {
|
Result GetKeyValueStoreItemForDebug(u64 *out_count, KeyValueStoreItemForDebug * const out_items, size_t out_items_count) {
|
||||||
/* Check preconditions. */
|
/* Check preconditions. */
|
||||||
AMS_ASSERT(out_count != nullptr);
|
AMS_ASSERT(out_count != nullptr);
|
||||||
|
@ -1466,7 +1466,7 @@ namespace ams::settings::impl {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the current item. */
|
/* Get the current item. */
|
||||||
KeyValueStoreItemForDebug &item = out_items[count++];
|
KeyValueStoreItemForDebug &item = out_items[count++];
|
||||||
|
|
||||||
/* Copy the map key and value to the item. */
|
/* Copy the map key and value to the item. */
|
||||||
|
@ -1494,7 +1494,7 @@ namespace ams::settings::impl {
|
||||||
/* Copy the key from the iterator to the output buffer. */
|
/* Copy the key from the iterator to the output buffer. */
|
||||||
const size_t key_size = std::min(out_buffer_size, std::min(iterator.entire_size - iterator.header_size, SettingsItemKeyLengthMax + 1));
|
const size_t key_size = std::min(out_buffer_size, std::min(iterator.entire_size - iterator.header_size, SettingsItemKeyLengthMax + 1));
|
||||||
std::strncpy(out_buffer, iterator.map_key + iterator.header_size, key_size);
|
std::strncpy(out_buffer, iterator.map_key + iterator.header_size, key_size);
|
||||||
|
|
||||||
/* Set the end of the key to null. */
|
/* Set the end of the key to null. */
|
||||||
if (key_size > 0) {
|
if (key_size > 0) {
|
||||||
out_buffer[key_size - 1] = '\x00';
|
out_buffer[key_size - 1] = '\x00';
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace ams::settings::impl {
|
||||||
const SettingsName &m_name;
|
const SettingsName &m_name;
|
||||||
public:
|
public:
|
||||||
explicit KeyValueStore(const SettingsName &name) : m_name(name) { /* ... */ }
|
explicit KeyValueStore(const SettingsName &name) : m_name(name) { /* ... */ }
|
||||||
|
|
||||||
Result CreateKeyIterator(KeyValueStoreKeyIterator *out);
|
Result CreateKeyIterator(KeyValueStoreKeyIterator *out);
|
||||||
Result GetValue(u64 *out_count, char *out_buffer, size_t out_buffer_size, const SettingsItemKey &item_key);
|
Result GetValue(u64 *out_count, char *out_buffer, size_t out_buffer_size, const SettingsItemKey &item_key);
|
||||||
Result GetValueSize(u64 *out_value_size, const SettingsItemKey &item_key);
|
Result GetValueSize(u64 *out_value_size, const SettingsItemKey &item_key);
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace ams::settings::impl {
|
||||||
s64 file_size = 0;
|
s64 file_size = 0;
|
||||||
R_TRY(fs::GetFileSize(std::addressof(file_size), file));
|
R_TRY(fs::GetFileSize(std::addressof(file_size), file));
|
||||||
AMS_ASSERT(0 <= file_size && file_size <= static_cast<s64>(sizeof(m_buffer)));
|
AMS_ASSERT(0 <= file_size && file_size <= static_cast<s64>(sizeof(m_buffer)));
|
||||||
R_UNLESS(file_size <= static_cast<s64>(sizeof(m_buffer)), ResultTooLargeSystemSaveData());
|
R_UNLESS(file_size <= static_cast<s64>(sizeof(m_buffer)), settings::ResultTooLargeSystemSaveData());
|
||||||
|
|
||||||
/* Read the save file. */
|
/* Read the save file. */
|
||||||
R_TRY(fs::ReadFile(file, 0, m_buffer, static_cast<size_t>(file_size)));
|
R_TRY(fs::ReadFile(file, 0, m_buffer, static_cast<size_t>(file_size)));
|
||||||
|
|
|
@ -51,9 +51,9 @@ namespace ams::updater {
|
||||||
|
|
||||||
/* Implementations. */
|
/* Implementations. */
|
||||||
Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size) {
|
Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size) {
|
||||||
R_UNLESS(work_buffer_size >= BctSize + EksSize, ResultTooSmallWorkBuffer());
|
R_UNLESS(work_buffer_size >= BctSize + EksSize, updater::ResultTooSmallWorkBuffer());
|
||||||
R_UNLESS(util::IsAligned(work_buffer, os::MemoryPageSize), ResultNotAlignedWorkBuffer());
|
R_UNLESS(util::IsAligned(work_buffer, os::MemoryPageSize), updater::ResultNotAlignedWorkBuffer());
|
||||||
R_UNLESS(util::IsAligned(work_buffer_size, 0x200), ResultNotAlignedWorkBuffer());
|
R_UNLESS(util::IsAligned(work_buffer_size, 0x200), updater::ResultNotAlignedWorkBuffer());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ namespace ams::updater {
|
||||||
/* Mount the boot image package. */
|
/* Mount the boot image package. */
|
||||||
const char *mount_name = GetMountName();
|
const char *mount_name = GetMountName();
|
||||||
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
||||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
R_CONVERT(fs::ResultTargetNotFound, updater::ResultBootImagePackageNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ namespace ams::updater {
|
||||||
/* Mount the boot image package. */
|
/* Mount the boot image package. */
|
||||||
const char *mount_name = GetMountName();
|
const char *mount_name = GetMountName();
|
||||||
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
||||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
R_CONVERT(fs::ResultTargetNotFound, updater::ResultBootImagePackageNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ namespace ams::updater {
|
||||||
/* Mount the boot image package. */
|
/* Mount the boot image package. */
|
||||||
const char *mount_name = GetMountName();
|
const char *mount_name = GetMountName();
|
||||||
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
||||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
R_CONVERT(fs::ResultTargetNotFound, updater::ResultBootImagePackageNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ namespace ams::updater {
|
||||||
/* Mount the boot image package. */
|
/* Mount the boot image package. */
|
||||||
const char *mount_name = GetMountName();
|
const char *mount_name = GetMountName();
|
||||||
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) {
|
||||||
R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound())
|
R_CONVERT(fs::ResultTargetNotFound, updater::ResultBootImagePackageNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
ON_SCOPE_EXIT { fs::Unmount(mount_name); };
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ namespace ams::updater {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CompareHash(const void *lhs, const void *rhs, size_t size) {
|
Result CompareHash(const void *lhs, const void *rhs, size_t size) {
|
||||||
R_UNLESS(crypto::IsSameBytes(lhs, rhs, size), ResultNeedsRepairBootImages());
|
R_UNLESS(crypto::IsSameBytes(lhs, rhs, size), updater::ResultNeedsRepairBootImages());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ namespace ams::updater {
|
||||||
const auto content_meta_type = GetContentMetaType(mode);
|
const auto content_meta_type = GetContentMetaType(mode);
|
||||||
|
|
||||||
auto count = db.ListContentMeta(keys, MaxContentMetas, content_meta_type);
|
auto count = db.ListContentMeta(keys, MaxContentMetas, content_meta_type);
|
||||||
R_UNLESS(count.total > 0, ResultBootImagePackageNotFound());
|
R_UNLESS(count.total > 0, updater::ResultBootImagePackageNotFound());
|
||||||
|
|
||||||
/* Output is sorted, return the lowest valid exfat entry. */
|
/* Output is sorted, return the lowest valid exfat entry. */
|
||||||
if (count.total > 1) {
|
if (count.total > 1) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace ams::updater {
|
||||||
|
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
R_TRY_CATCH(fs::OpenFile(std::addressof(file), bip_path, fs::OpenMode_Read)) {
|
R_TRY_CATCH(fs::OpenFile(std::addressof(file), bip_path, fs::OpenMode_Read)) {
|
||||||
R_CONVERT(fs::ResultPathNotFound, ResultInvalidBootImagePackage())
|
R_CONVERT(fs::ResultPathNotFound, updater::ResultInvalidBootImagePackage())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace ams::updater {
|
||||||
/* Open the file. */
|
/* Open the file. */
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
R_TRY_CATCH(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read)) {
|
R_TRY_CATCH(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read)) {
|
||||||
R_CONVERT(fs::ResultPathNotFound, ResultInvalidBootImagePackage())
|
R_CONVERT(fs::ResultPathNotFound, updater::ResultInvalidBootImagePackage())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace ams::updater {
|
||||||
/* Open the file. */
|
/* Open the file. */
|
||||||
fs::FileHandle file;
|
fs::FileHandle file;
|
||||||
R_TRY_CATCH(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read)) {
|
R_TRY_CATCH(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read)) {
|
||||||
R_CONVERT(fs::ResultPathNotFound, ResultInvalidBootImagePackage())
|
R_CONVERT(fs::ResultPathNotFound, updater::ResultInvalidBootImagePackage())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
ON_SCOPE_EXIT { fs::CloseFile(file); };
|
||||||
|
|
||||||
|
|
|
@ -122,25 +122,25 @@ namespace ams::settings::fwdbg {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ValidateSettingsName(const char *name) {
|
Result ValidateSettingsName(const char *name) {
|
||||||
R_UNLESS(name != nullptr, ResultNullSettingsName());
|
R_UNLESS(name != nullptr, settings::ResultNullSettingsName());
|
||||||
const size_t len = strnlen(name, SettingsNameLengthMax + 1);
|
const size_t len = strnlen(name, SettingsNameLengthMax + 1);
|
||||||
R_UNLESS(len > 0, ResultEmptySettingsName());
|
R_UNLESS(len > 0, settings::ResultEmptySettingsName());
|
||||||
R_UNLESS(len <= SettingsNameLengthMax, ResultTooLongSettingsName());
|
R_UNLESS(len <= SettingsNameLengthMax, settings::ResultTooLongSettingsName());
|
||||||
R_UNLESS(IsValidSettingsFormat(name, len), ResultInvalidFormatSettingsName());
|
R_UNLESS(IsValidSettingsFormat(name, len), settings::ResultInvalidFormatSettingsName());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ValidateSettingsItemKey(const char *key) {
|
Result ValidateSettingsItemKey(const char *key) {
|
||||||
R_UNLESS(key != nullptr, ResultNullSettingsName());
|
R_UNLESS(key != nullptr, settings::ResultNullSettingsName());
|
||||||
const size_t len = strnlen(key, SettingsItemKeyLengthMax + 1);
|
const size_t len = strnlen(key, SettingsItemKeyLengthMax + 1);
|
||||||
R_UNLESS(len > 0, ResultEmptySettingsItemKey());
|
R_UNLESS(len > 0, settings::ResultEmptySettingsItemKey());
|
||||||
R_UNLESS(len <= SettingsNameLengthMax, ResultTooLongSettingsItemKey());
|
R_UNLESS(len <= SettingsNameLengthMax, settings::ResultTooLongSettingsItemKey());
|
||||||
R_UNLESS(IsValidSettingsFormat(key, len), ResultInvalidFormatSettingsItemKey());
|
R_UNLESS(IsValidSettingsFormat(key, len), settings::ResultInvalidFormatSettingsItemKey());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AllocateValue(void **out, size_t size) {
|
Result AllocateValue(void **out, size_t size) {
|
||||||
R_UNLESS(g_allocated_value_storage_size + size <= sizeof(g_value_storage), ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(g_allocated_value_storage_size + size <= sizeof(g_value_storage), settings::ResultSettingsItemValueAllocationFailed());
|
||||||
|
|
||||||
*out = g_value_storage + g_allocated_value_storage_size;
|
*out = g_value_storage + g_allocated_value_storage_size;
|
||||||
g_allocated_value_storage_size += size;
|
g_allocated_value_storage_size += size;
|
||||||
|
@ -158,7 +158,7 @@ namespace ams::settings::fwdbg {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ResultSettingsItemKeyAllocationFailed();
|
return settings::ResultSettingsItemKeyAllocationFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FindSettingsItemKey(const char **out, const char *key) {
|
Result FindSettingsItemKey(const char **out, const char *key) {
|
||||||
|
@ -172,7 +172,7 @@ namespace ams::settings::fwdbg {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ResultSettingsItemKeyAllocationFailed();
|
return settings::ResultSettingsItemKeyAllocationFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -196,8 +196,8 @@ namespace ams::settings::fwdbg {
|
||||||
auto *begin = g_entries;
|
auto *begin = g_entries;
|
||||||
auto *end = begin + g_num_entries;
|
auto *end = begin + g_num_entries;
|
||||||
auto it = std::lower_bound(begin, end, test_entry);
|
auto it = std::lower_bound(begin, end, test_entry);
|
||||||
R_UNLESS(it != end, ResultSettingsItemNotFound());
|
R_UNLESS(it != end, settings::ResultSettingsItemNotFound());
|
||||||
R_UNLESS(*it == test_entry, ResultSettingsItemNotFound());
|
R_UNLESS(*it == test_entry, settings::ResultSettingsItemNotFound());
|
||||||
|
|
||||||
*out = &*it;
|
*out = &*it;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -208,7 +208,7 @@ namespace ams::settings::fwdbg {
|
||||||
const char *value_str = delimiter + 1;
|
const char *value_str = delimiter + 1;
|
||||||
const char *type = val_tup;
|
const char *type = val_tup;
|
||||||
|
|
||||||
R_UNLESS(delimiter != nullptr, ResultInvalidFormatSettingsItemValue());
|
R_UNLESS(delimiter != nullptr, settings::ResultInvalidFormatSettingsItemValue());
|
||||||
|
|
||||||
while (std::isspace(static_cast<unsigned char>(*type)) && type != delimiter) {
|
while (std::isspace(static_cast<unsigned char>(*type)) && type != delimiter) {
|
||||||
type++;
|
type++;
|
||||||
|
@ -216,8 +216,8 @@ namespace ams::settings::fwdbg {
|
||||||
|
|
||||||
const size_t type_len = delimiter - type;
|
const size_t type_len = delimiter - type;
|
||||||
const size_t value_len = strlen(value_str);
|
const size_t value_len = strlen(value_str);
|
||||||
R_UNLESS(type_len > 0, ResultInvalidFormatSettingsItemValue());
|
R_UNLESS(type_len > 0, settings::ResultInvalidFormatSettingsItemValue());
|
||||||
R_UNLESS(value_len > 0, ResultInvalidFormatSettingsItemValue());
|
R_UNLESS(value_len > 0, settings::ResultInvalidFormatSettingsItemValue());
|
||||||
|
|
||||||
/* Create new value. */
|
/* Create new value. */
|
||||||
SdKeyValueStoreEntry new_value = {};
|
SdKeyValueStoreEntry new_value = {};
|
||||||
|
@ -232,9 +232,9 @@ namespace ams::settings::fwdbg {
|
||||||
std::memcpy(new_value.value, value_str, size);
|
std::memcpy(new_value.value, value_str, size);
|
||||||
new_value.value_size = size;
|
new_value.value_size = size;
|
||||||
} else if (strncasecmp(type, "hex", type_len) == 0 || strncasecmp(type, "bytes", type_len) == 0) {
|
} else if (strncasecmp(type, "hex", type_len) == 0 || strncasecmp(type, "bytes", type_len) == 0) {
|
||||||
R_UNLESS(value_len > 0, ResultInvalidFormatSettingsItemValue());
|
R_UNLESS(value_len > 0, settings::ResultInvalidFormatSettingsItemValue());
|
||||||
R_UNLESS(value_len % 2 == 0, ResultInvalidFormatSettingsItemValue());
|
R_UNLESS(value_len % 2 == 0, settings::ResultInvalidFormatSettingsItemValue());
|
||||||
R_UNLESS(IsHexadecimal(value_str), ResultInvalidFormatSettingsItemValue());
|
R_UNLESS(IsHexadecimal(value_str), settings::ResultInvalidFormatSettingsItemValue());
|
||||||
|
|
||||||
const size_t size = value_len / 2;
|
const size_t size = value_len / 2;
|
||||||
R_TRY(AllocateValue(&new_value.value, size));
|
R_TRY(AllocateValue(&new_value.value, size));
|
||||||
|
@ -253,7 +253,7 @@ namespace ams::settings::fwdbg {
|
||||||
} else if (strncasecmp(type, "u64", type_len) == 0) {
|
} else if (strncasecmp(type, "u64", type_len) == 0) {
|
||||||
R_TRY((ParseSettingsItemIntegralValue<u64>(new_value, value_str)));
|
R_TRY((ParseSettingsItemIntegralValue<u64>(new_value, value_str)));
|
||||||
} else {
|
} else {
|
||||||
return ResultInvalidFormatSettingsItemValue();
|
return settings::ResultInvalidFormatSettingsItemValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the entry. */
|
/* Insert the entry. */
|
||||||
|
@ -266,7 +266,7 @@ namespace ams::settings::fwdbg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_UNLESS(inserted, ResultSettingsItemValueAllocationFailed());
|
R_UNLESS(inserted, settings::ResultSettingsItemValueAllocationFailed());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ namespace ams::settings::fwdbg {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result GetSdCardKeyValueStoreSettingsItemValue(size_t *out_size, void *dst, size_t dst_size, const char *name, const char *key) {
|
Result GetSdCardKeyValueStoreSettingsItemValue(size_t *out_size, void *dst, size_t dst_size, const char *name, const char *key) {
|
||||||
R_UNLESS(dst != nullptr, ResultNullSettingsItemValueBuffer());
|
R_UNLESS(dst != nullptr, settings::ResultNullSettingsItemValueBuffer());
|
||||||
|
|
||||||
SdKeyValueStoreEntry *entry = nullptr;
|
SdKeyValueStoreEntry *entry = nullptr;
|
||||||
R_TRY(GetEntry(&entry, name, key));
|
R_TRY(GetEntry(&entry, name, key));
|
||||||
|
|
|
@ -229,29 +229,29 @@ namespace ams::creport {
|
||||||
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
|
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
|
||||||
switch (d.info.exception.type) {
|
switch (d.info.exception.type) {
|
||||||
case svc::DebugException_UndefinedInstruction:
|
case svc::DebugException_UndefinedInstruction:
|
||||||
this->result = ResultUndefinedInstruction();
|
this->result = creport::ResultUndefinedInstruction();
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_InstructionAbort:
|
case svc::DebugException_InstructionAbort:
|
||||||
this->result = ResultInstructionAbort();
|
this->result = creport::ResultInstructionAbort();
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_DataAbort:
|
case svc::DebugException_DataAbort:
|
||||||
this->result = ResultDataAbort();
|
this->result = creport::ResultDataAbort();
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_AlignmentFault:
|
case svc::DebugException_AlignmentFault:
|
||||||
this->result = ResultAlignmentFault();
|
this->result = creport::ResultAlignmentFault();
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_UserBreak:
|
case svc::DebugException_UserBreak:
|
||||||
this->result = ResultUserBreak();
|
this->result = creport::ResultUserBreak();
|
||||||
/* Try to parse out the user break result. */
|
/* Try to parse out the user break result. */
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||||
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(this->result)), this->debug_handle, d.info.exception.specific.user_break.address, sizeof(this->result));
|
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(this->result)), this->debug_handle, d.info.exception.specific.user_break.address, sizeof(this->result));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_UndefinedSystemCall:
|
case svc::DebugException_UndefinedSystemCall:
|
||||||
this->result = ResultUndefinedSystemCall();
|
this->result = creport::ResultUndefinedSystemCall();
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_MemorySystemError:
|
case svc::DebugException_MemorySystemError:
|
||||||
this->result = ResultMemorySystemError();
|
this->result = creport::ResultMemorySystemError();
|
||||||
break;
|
break;
|
||||||
case svc::DebugException_DebuggerAttached:
|
case svc::DebugException_DebuggerAttached:
|
||||||
case svc::DebugException_BreakPoint:
|
case svc::DebugException_BreakPoint:
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace ams::creport {
|
||||||
private:
|
private:
|
||||||
os::NativeHandle debug_handle = os::InvalidNativeHandle;
|
os::NativeHandle debug_handle = os::InvalidNativeHandle;
|
||||||
bool has_extra_info = true;
|
bool has_extra_info = true;
|
||||||
Result result = ResultIncompleteReport();
|
Result result = creport::ResultIncompleteReport();
|
||||||
|
|
||||||
/* Meta, used for building module/thread list. */
|
/* Meta, used for building module/thread list. */
|
||||||
ThreadTlsMap thread_tls_map = {};
|
ThreadTlsMap thread_tls_map = {};
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace ams::dmnt::cheat {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheatService::ForceOpenCheatProcess() {
|
Result CheatService::ForceOpenCheatProcess() {
|
||||||
R_UNLESS(R_SUCCEEDED(dmnt::cheat::impl::ForceOpenCheatProcess()), ResultCheatNotAttached());
|
R_UNLESS(R_SUCCEEDED(dmnt::cheat::impl::ForceOpenCheatProcess()), dmnt::cheat::ResultCheatNotAttached());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,17 +61,17 @@ namespace ams::dmnt::cheat {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheatService::GetCheatProcessMappings(const sf::OutArray<svc::MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset) {
|
Result CheatService::GetCheatProcessMappings(const sf::OutArray<svc::MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset) {
|
||||||
R_UNLESS(mappings.GetPointer() != nullptr, ResultCheatNullBuffer());
|
R_UNLESS(mappings.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||||
return dmnt::cheat::impl::GetCheatProcessMappings(mappings.GetPointer(), mappings.GetSize(), out_count.GetPointer(), offset);
|
return dmnt::cheat::impl::GetCheatProcessMappings(mappings.GetPointer(), mappings.GetSize(), out_count.GetPointer(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheatService::ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size) {
|
Result CheatService::ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size) {
|
||||||
R_UNLESS(buffer.GetPointer() != nullptr, ResultCheatNullBuffer());
|
R_UNLESS(buffer.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||||
return dmnt::cheat::impl::ReadCheatProcessMemory(address, buffer.GetPointer(), std::min(out_size, buffer.GetSize()));
|
return dmnt::cheat::impl::ReadCheatProcessMemory(address, buffer.GetPointer(), std::min(out_size, buffer.GetSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheatService::WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size) {
|
Result CheatService::WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size) {
|
||||||
R_UNLESS(buffer.GetPointer() != nullptr, ResultCheatNullBuffer());
|
R_UNLESS(buffer.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||||
return dmnt::cheat::impl::WriteCheatProcessMemory(address, buffer.GetPointer(), std::min(in_size, buffer.GetSize()));
|
return dmnt::cheat::impl::WriteCheatProcessMemory(address, buffer.GetPointer(), std::min(in_size, buffer.GetSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ namespace ams::dmnt::cheat {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheatService::GetCheats(const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset) {
|
Result CheatService::GetCheats(const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset) {
|
||||||
R_UNLESS(cheats.GetPointer() != nullptr, ResultCheatNullBuffer());
|
R_UNLESS(cheats.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||||
return dmnt::cheat::impl::GetCheats(cheats.GetPointer(), cheats.GetSize(), out_count.GetPointer(), offset);
|
return dmnt::cheat::impl::GetCheats(cheats.GetPointer(), cheats.GetSize(), out_count.GetPointer(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ namespace ams::dmnt::cheat {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheatService::GetFrozenAddresses(const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset) {
|
Result CheatService::GetFrozenAddresses(const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset) {
|
||||||
R_UNLESS(addresses.GetPointer() != nullptr, ResultCheatNullBuffer());
|
R_UNLESS(addresses.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||||
return dmnt::cheat::impl::GetFrozenAddresses(addresses.GetPointer(), addresses.GetSize(), out_count.GetPointer(), offset);
|
return dmnt::cheat::impl::GetFrozenAddresses(addresses.GetPointer(), addresses.GetSize(), out_count.GetPointer(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,9 +143,9 @@ namespace ams::dmnt::cheat {
|
||||||
|
|
||||||
Result CheatService::EnableFrozenAddress(sf::Out<u64> out_value, u64 address, u64 width) {
|
Result CheatService::EnableFrozenAddress(sf::Out<u64> out_value, u64 address, u64 width) {
|
||||||
/* Width needs to be a power of two <= 8. */
|
/* Width needs to be a power of two <= 8. */
|
||||||
R_UNLESS(width > 0, ResultFrozenAddressInvalidWidth());
|
R_UNLESS(width > 0, dmnt::cheat::ResultFrozenAddressInvalidWidth());
|
||||||
R_UNLESS(width <= sizeof(u64), ResultFrozenAddressInvalidWidth());
|
R_UNLESS(width <= sizeof(u64), dmnt::cheat::ResultFrozenAddressInvalidWidth());
|
||||||
R_UNLESS((width & (width - 1)) == 0, ResultFrozenAddressInvalidWidth());
|
R_UNLESS((width & (width - 1)) == 0, dmnt::cheat::ResultFrozenAddressInvalidWidth());
|
||||||
return dmnt::cheat::impl::EnableFrozenAddress(out_value.GetPointer(), address, width);
|
return dmnt::cheat::impl::EnableFrozenAddress(out_value.GetPointer(), address, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EnsureCheatProcess() {
|
Result EnsureCheatProcess() {
|
||||||
R_UNLESS(this->HasActiveCheatProcess(), ResultCheatNotAttached());
|
R_UNLESS(this->HasActiveCheatProcess(), dmnt::cheat::ResultCheatNotAttached());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,8 +480,8 @@ namespace ams::dmnt::cheat::impl {
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
const CheatEntry *entry = this->GetCheatEntryById(cheat_id);
|
const CheatEntry *entry = this->GetCheatEntryById(cheat_id);
|
||||||
R_UNLESS(entry != nullptr, ResultCheatUnknownId());
|
R_UNLESS(entry != nullptr, dmnt::cheat::ResultCheatUnknownId());
|
||||||
R_UNLESS(entry->definition.num_opcodes != 0, ResultCheatUnknownId());
|
R_UNLESS(entry->definition.num_opcodes != 0, dmnt::cheat::ResultCheatUnknownId());
|
||||||
|
|
||||||
*out_cheat = *entry;
|
*out_cheat = *entry;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -493,10 +493,10 @@ namespace ams::dmnt::cheat::impl {
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
CheatEntry *entry = this->GetCheatEntryById(cheat_id);
|
CheatEntry *entry = this->GetCheatEntryById(cheat_id);
|
||||||
R_UNLESS(entry != nullptr, ResultCheatUnknownId());
|
R_UNLESS(entry != nullptr, dmnt::cheat::ResultCheatUnknownId());
|
||||||
R_UNLESS(entry->definition.num_opcodes != 0, ResultCheatUnknownId());
|
R_UNLESS(entry->definition.num_opcodes != 0, dmnt::cheat::ResultCheatUnknownId());
|
||||||
|
|
||||||
R_UNLESS(cheat_id != 0, ResultCheatCannotDisable());
|
R_UNLESS(cheat_id != 0, dmnt::cheat::ResultCheatCannotDisable());
|
||||||
|
|
||||||
entry->enabled = !entry->enabled;
|
entry->enabled = !entry->enabled;
|
||||||
|
|
||||||
|
@ -511,11 +511,11 @@ namespace ams::dmnt::cheat::impl {
|
||||||
|
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
R_UNLESS(def.num_opcodes != 0, ResultCheatInvalid());
|
R_UNLESS(def.num_opcodes != 0, dmnt::cheat::ResultCheatInvalid());
|
||||||
R_UNLESS(def.num_opcodes <= util::size(def.opcodes), ResultCheatInvalid());
|
R_UNLESS(def.num_opcodes <= util::size(def.opcodes), dmnt::cheat::ResultCheatInvalid());
|
||||||
|
|
||||||
CheatEntry *new_entry = this->GetFreeCheatEntry();
|
CheatEntry *new_entry = this->GetFreeCheatEntry();
|
||||||
R_UNLESS(new_entry != nullptr, ResultCheatOutOfResource());
|
R_UNLESS(new_entry != nullptr, dmnt::cheat::ResultCheatOutOfResource());
|
||||||
|
|
||||||
new_entry->enabled = enabled;
|
new_entry->enabled = enabled;
|
||||||
new_entry->definition = def;
|
new_entry->definition = def;
|
||||||
|
@ -533,7 +533,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
std::scoped_lock lk(this->cheat_lock);
|
std::scoped_lock lk(this->cheat_lock);
|
||||||
|
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
R_UNLESS(cheat_id < MaxCheatCount, ResultCheatUnknownId());
|
R_UNLESS(cheat_id < MaxCheatCount, dmnt::cheat::ResultCheatUnknownId());
|
||||||
|
|
||||||
this->ResetCheatEntry(cheat_id);
|
this->ResetCheatEntry(cheat_id);
|
||||||
|
|
||||||
|
@ -548,8 +548,8 @@ namespace ams::dmnt::cheat::impl {
|
||||||
|
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
R_UNLESS(def.num_opcodes != 0, ResultCheatInvalid());
|
R_UNLESS(def.num_opcodes != 0, dmnt::cheat::ResultCheatInvalid());
|
||||||
R_UNLESS(def.num_opcodes <= util::size(def.opcodes), ResultCheatInvalid());
|
R_UNLESS(def.num_opcodes <= util::size(def.opcodes), dmnt::cheat::ResultCheatInvalid());
|
||||||
|
|
||||||
CheatEntry *master_entry = this->cheat_entries + 0;
|
CheatEntry *master_entry = this->cheat_entries + 0;
|
||||||
|
|
||||||
|
@ -566,7 +566,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
std::scoped_lock lk(this->cheat_lock);
|
std::scoped_lock lk(this->cheat_lock);
|
||||||
|
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
R_UNLESS(which < CheatVirtualMachine::NumStaticRegisters, ResultCheatInvalid());
|
R_UNLESS(which < CheatVirtualMachine::NumStaticRegisters, dmnt::cheat::ResultCheatInvalid());
|
||||||
|
|
||||||
*out = this->cheat_vm.GetStaticRegister(which);
|
*out = this->cheat_vm.GetStaticRegister(which);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -576,7 +576,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
std::scoped_lock lk(this->cheat_lock);
|
std::scoped_lock lk(this->cheat_lock);
|
||||||
|
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
R_UNLESS(which < CheatVirtualMachine::NumStaticRegisters, ResultCheatInvalid());
|
R_UNLESS(which < CheatVirtualMachine::NumStaticRegisters, dmnt::cheat::ResultCheatInvalid());
|
||||||
|
|
||||||
this->cheat_vm.SetStaticRegister(which, value);
|
this->cheat_vm.SetStaticRegister(which, value);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -629,7 +629,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
const auto it = this->frozen_addresses_map.find_key(address);
|
const auto it = this->frozen_addresses_map.find_key(address);
|
||||||
R_UNLESS(it != this->frozen_addresses_map.end(), ResultFrozenAddressNotFound());
|
R_UNLESS(it != this->frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressNotFound());
|
||||||
|
|
||||||
frz_addr->address = it->GetAddress();
|
frz_addr->address = it->GetAddress();
|
||||||
frz_addr->value = it->GetValue();
|
frz_addr->value = it->GetValue();
|
||||||
|
@ -642,14 +642,14 @@ namespace ams::dmnt::cheat::impl {
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
const auto it = this->frozen_addresses_map.find_key(address);
|
const auto it = this->frozen_addresses_map.find_key(address);
|
||||||
R_UNLESS(it == this->frozen_addresses_map.end(), ResultFrozenAddressAlreadyExists());
|
R_UNLESS(it == this->frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressAlreadyExists());
|
||||||
|
|
||||||
FrozenAddressValue value = {};
|
FrozenAddressValue value = {};
|
||||||
value.width = width;
|
value.width = width;
|
||||||
R_TRY(this->ReadCheatProcessMemoryUnsafe(address, &value.value, width));
|
R_TRY(this->ReadCheatProcessMemoryUnsafe(address, &value.value, width));
|
||||||
|
|
||||||
FrozenAddressMapEntry *entry = AllocateFrozenAddress(address, value);
|
FrozenAddressMapEntry *entry = AllocateFrozenAddress(address, value);
|
||||||
R_UNLESS(entry != nullptr, ResultFrozenAddressOutOfResource());
|
R_UNLESS(entry != nullptr, dmnt::cheat::ResultFrozenAddressOutOfResource());
|
||||||
|
|
||||||
this->frozen_addresses_map.insert(*entry);
|
this->frozen_addresses_map.insert(*entry);
|
||||||
*out_value = value.value;
|
*out_value = value.value;
|
||||||
|
@ -662,7 +662,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
R_TRY(this->EnsureCheatProcess());
|
R_TRY(this->EnsureCheatProcess());
|
||||||
|
|
||||||
const auto it = this->frozen_addresses_map.find_key(address);
|
const auto it = this->frozen_addresses_map.find_key(address);
|
||||||
R_UNLESS(it != this->frozen_addresses_map.end(), ResultFrozenAddressNotFound());
|
R_UNLESS(it != this->frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressNotFound());
|
||||||
|
|
||||||
FrozenAddressMapEntry *entry = std::addressof(*it);
|
FrozenAddressMapEntry *entry = std::addressof(*it);
|
||||||
this->frozen_addresses_map.erase(it);
|
this->frozen_addresses_map.erase(it);
|
||||||
|
@ -820,7 +820,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
|
|
||||||
/* If new process launch, we may not want to actually attach. */
|
/* If new process launch, we may not want to actually attach. */
|
||||||
if (on_process_launch) {
|
if (on_process_launch) {
|
||||||
R_UNLESS(status.IsCheatEnabled(), ResultCheatNotAttached());
|
R_UNLESS(status.IsCheatEnabled(), dmnt::cheat::ResultCheatNotAttached());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +841,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
} else if (num_modules == 1 && !on_process_launch) {
|
} else if (num_modules == 1 && !on_process_launch) {
|
||||||
proc_module = &proc_modules[0];
|
proc_module = &proc_modules[0];
|
||||||
} else {
|
} else {
|
||||||
return ResultCheatNotAttached();
|
return dmnt::cheat::ResultCheatNotAttached();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->cheat_process_metadata.main_nso_extents.base = proc_module->base_address;
|
this->cheat_process_metadata.main_nso_extents.base = proc_module->base_address;
|
||||||
|
@ -853,7 +853,7 @@ namespace ams::dmnt::cheat::impl {
|
||||||
if (!this->LoadCheats(this->cheat_process_metadata.program_id, this->cheat_process_metadata.main_nso_build_id) ||
|
if (!this->LoadCheats(this->cheat_process_metadata.program_id, this->cheat_process_metadata.main_nso_build_id) ||
|
||||||
!this->LoadCheatToggles(this->cheat_process_metadata.program_id)) {
|
!this->LoadCheatToggles(this->cheat_process_metadata.program_id)) {
|
||||||
/* If new process launch, require success. */
|
/* If new process launch, require success. */
|
||||||
R_UNLESS(!on_process_launch, ResultCheatNotAttached());
|
R_UNLESS(!on_process_launch, dmnt::cheat::ResultCheatNotAttached());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open a debug handle. */
|
/* Open a debug handle. */
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ams::fatal::srv {
|
||||||
std::scoped_lock lk{this->lock};
|
std::scoped_lock lk{this->lock};
|
||||||
|
|
||||||
/* Only allow GetEvent to succeed NumFatalEvents times. */
|
/* Only allow GetEvent to succeed NumFatalEvents times. */
|
||||||
R_UNLESS(this->num_events_gotten < FatalEventManager::NumFatalEvents, ResultTooManyEvents());
|
R_UNLESS(this->num_events_gotten < FatalEventManager::NumFatalEvents, fatal::ResultTooManyEvents());
|
||||||
|
|
||||||
*out = std::addressof(this->events[this->num_events_gotten++]);
|
*out = std::addressof(this->events[this->num_events_gotten++]);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace ams::fatal::srv {
|
||||||
bool has_thrown;
|
bool has_thrown;
|
||||||
private:
|
private:
|
||||||
Result TrySetHasThrown() {
|
Result TrySetHasThrown() {
|
||||||
R_UNLESS(!this->has_thrown, ResultAlreadyThrown());
|
R_UNLESS(!this->has_thrown, fatal::ResultAlreadyThrown());
|
||||||
this->has_thrown = true;
|
this->has_thrown = true;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace ams::ldr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result LoaderService::GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id) {
|
Result LoaderService::GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id) {
|
||||||
R_UNLESS(out.GetSize() <= std::numeric_limits<s32>::max(), ResultInvalidSize());
|
R_UNLESS(out.GetSize() <= std::numeric_limits<s32>::max(), ldr::ResultInvalidSize());
|
||||||
return ldr::ro::GetProcessModuleInfo(count.GetPointer(), out.GetPointer(), out.GetSize(), process_id);
|
return ldr::ro::GetProcessModuleInfo(count.GetPointer(), out.GetPointer(), out.GetSize(), process_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,16 +43,16 @@ namespace ams::ldr {
|
||||||
|
|
||||||
/* Helpers. */
|
/* Helpers. */
|
||||||
Result ValidateSubregion(size_t allowed_start, size_t allowed_end, size_t start, size_t size, size_t min_size = 0) {
|
Result ValidateSubregion(size_t allowed_start, size_t allowed_end, size_t start, size_t size, size_t min_size = 0) {
|
||||||
R_UNLESS(size >= min_size, ResultInvalidMeta());
|
R_UNLESS(size >= min_size, ldr::ResultInvalidMeta());
|
||||||
R_UNLESS(allowed_start <= start, ResultInvalidMeta());
|
R_UNLESS(allowed_start <= start, ldr::ResultInvalidMeta());
|
||||||
R_UNLESS(start <= allowed_end, ResultInvalidMeta());
|
R_UNLESS(start <= allowed_end, ldr::ResultInvalidMeta());
|
||||||
R_UNLESS(start + size <= allowed_end, ResultInvalidMeta());
|
R_UNLESS(start + size <= allowed_end, ldr::ResultInvalidMeta());
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ValidateNpdm(const Npdm *npdm, size_t size) {
|
Result ValidateNpdm(const Npdm *npdm, size_t size) {
|
||||||
/* Validate magic. */
|
/* Validate magic. */
|
||||||
R_UNLESS(npdm->magic == Npdm::Magic, ResultInvalidMeta());
|
R_UNLESS(npdm->magic == Npdm::Magic, ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Validate flags. */
|
/* Validate flags. */
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
@ -69,7 +69,7 @@ namespace ams::ldr {
|
||||||
/* We set the "DisableDeviceAddressSpaceMerge" bit on all versions, so be permissive with it. */
|
/* We set the "DisableDeviceAddressSpaceMerge" bit on all versions, so be permissive with it. */
|
||||||
mask &= ~0x20;
|
mask &= ~0x20;
|
||||||
|
|
||||||
R_UNLESS(!(npdm->flags & mask), ResultInvalidMeta());
|
R_UNLESS(!(npdm->flags & mask), ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Validate Acid extents. */
|
/* Validate Acid extents. */
|
||||||
R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid)));
|
R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid)));
|
||||||
|
@ -82,11 +82,11 @@ namespace ams::ldr {
|
||||||
|
|
||||||
Result ValidateAcid(const Acid *acid, size_t size) {
|
Result ValidateAcid(const Acid *acid, size_t size) {
|
||||||
/* Validate magic. */
|
/* Validate magic. */
|
||||||
R_UNLESS(acid->magic == Acid::Magic, ResultInvalidMeta());
|
R_UNLESS(acid->magic == Acid::Magic, ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Validate that the acid is for production if not development. */
|
/* Validate that the acid is for production if not development. */
|
||||||
if (!IsDevelopmentForAcidProductionCheck()) {
|
if (!IsDevelopmentForAcidProductionCheck()) {
|
||||||
R_UNLESS((acid->flags & Acid::AcidFlag_Production) != 0, ResultInvalidMeta());
|
R_UNLESS((acid->flags & Acid::AcidFlag_Production) != 0, ldr::ResultInvalidMeta());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate Fac, Sac, Kac. */
|
/* Validate Fac, Sac, Kac. */
|
||||||
|
@ -99,7 +99,7 @@ namespace ams::ldr {
|
||||||
|
|
||||||
Result ValidateAci(const Aci *aci, size_t size) {
|
Result ValidateAci(const Aci *aci, size_t size) {
|
||||||
/* Validate magic. */
|
/* Validate magic. */
|
||||||
R_UNLESS(aci->magic == Aci::Magic, ResultInvalidMeta());
|
R_UNLESS(aci->magic == Aci::Magic, ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Validate Fah, Sac, Kac. */
|
/* Validate Fah, Sac, Kac. */
|
||||||
R_TRY(ValidateSubregion(sizeof(Aci), size, aci->fah_offset, aci->fah_size));
|
R_TRY(ValidateSubregion(sizeof(Aci), size, aci->fah_offset, aci->fah_size));
|
||||||
|
@ -130,7 +130,7 @@ namespace ams::ldr {
|
||||||
const u8 *msg = meta->acid->modulus;
|
const u8 *msg = meta->acid->modulus;
|
||||||
const size_t msg_size = meta->acid->size;
|
const size_t msg_size = meta->acid->size;
|
||||||
const bool is_signature_valid = crypto::VerifyRsa2048PssSha256(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size);
|
const bool is_signature_valid = crypto::VerifyRsa2048PssSha256(sig, sig_size, mod, mod_size, exp, exp_size, msg, msg_size);
|
||||||
R_UNLESS(is_signature_valid || !IsEnabledProgramVerification(), ResultInvalidAcidSignature());
|
R_UNLESS(is_signature_valid || !IsEnabledProgramVerification(), ldr::ResultInvalidAcidSignature());
|
||||||
|
|
||||||
meta->check_verification_data = is_signature_valid;
|
meta->check_verification_data = is_signature_valid;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -147,12 +147,12 @@ namespace ams::ldr {
|
||||||
R_TRY(fs::GetFileSize(std::addressof(npdm_size), file));
|
R_TRY(fs::GetFileSize(std::addressof(npdm_size), file));
|
||||||
|
|
||||||
/* Read data into cache buffer. */
|
/* Read data into cache buffer. */
|
||||||
R_UNLESS(npdm_size <= static_cast<s64>(MetaCacheBufferSize), ResultTooLargeMeta());
|
R_UNLESS(npdm_size <= static_cast<s64>(MetaCacheBufferSize), ldr::ResultTooLargeMeta());
|
||||||
R_TRY(fs::ReadFile(file, 0, cache->buffer, npdm_size));
|
R_TRY(fs::ReadFile(file, 0, cache->buffer, npdm_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure size is big enough. */
|
/* Ensure size is big enough. */
|
||||||
R_UNLESS(npdm_size >= static_cast<s64>(sizeof(Npdm)), ResultInvalidMeta());
|
R_UNLESS(npdm_size >= static_cast<s64>(sizeof(Npdm)), ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Validate the meta. */
|
/* Validate the meta. */
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace ams::ldr {
|
||||||
|
|
||||||
for (size_t i = 0; i < num_entries; i++) {
|
for (size_t i = 0; i < num_entries; i++) {
|
||||||
if (entries[i].program_id == program_id) {
|
if (entries[i].program_id == program_id) {
|
||||||
R_UNLESS(entries[i].version <= version, ResultInvalidVersion());
|
R_UNLESS(entries[i].version <= version, ldr::ResultInvalidVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -142,7 +142,7 @@ namespace ams::ldr {
|
||||||
#define COPY_ACCESS_CONTROL(source, which) \
|
#define COPY_ACCESS_CONTROL(source, which) \
|
||||||
({ \
|
({ \
|
||||||
const size_t size = meta->source->which##_size; \
|
const size_t size = meta->source->which##_size; \
|
||||||
R_UNLESS(offset + size <= sizeof(out->ac_buffer), ResultInternalError()); \
|
R_UNLESS(offset + size <= sizeof(out->ac_buffer), ldr::ResultInternalError()); \
|
||||||
out->source##_##which##_size = size; \
|
out->source##_##which##_size = size; \
|
||||||
std::memcpy(out->ac_buffer + offset, meta->source##_##which, size); \
|
std::memcpy(out->ac_buffer + offset, meta->source##_##which, size); \
|
||||||
offset += size; \
|
offset += size; \
|
||||||
|
@ -189,7 +189,7 @@ namespace ams::ldr {
|
||||||
/* Read NSO header. */
|
/* Read NSO header. */
|
||||||
size_t read_size;
|
size_t read_size;
|
||||||
R_TRY(fs::ReadFile(std::addressof(read_size), file, 0, nso_headers + i, sizeof(*nso_headers)));
|
R_TRY(fs::ReadFile(std::addressof(read_size), file, 0, nso_headers + i, sizeof(*nso_headers)));
|
||||||
R_UNLESS(read_size == sizeof(*nso_headers), ResultInvalidNso());
|
R_UNLESS(read_size == sizeof(*nso_headers), ldr::ResultInvalidNso());
|
||||||
|
|
||||||
has_nso[i] = true;
|
has_nso[i] = true;
|
||||||
}
|
}
|
||||||
|
@ -200,18 +200,18 @@ namespace ams::ldr {
|
||||||
|
|
||||||
Result ValidateNsoHeaders(const NsoHeader *nso_headers, const bool *has_nso) {
|
Result ValidateNsoHeaders(const NsoHeader *nso_headers, const bool *has_nso) {
|
||||||
/* We must always have a main. */
|
/* We must always have a main. */
|
||||||
R_UNLESS(has_nso[Nso_Main], ResultInvalidNso());
|
R_UNLESS(has_nso[Nso_Main], ldr::ResultInvalidNso());
|
||||||
|
|
||||||
/* If we don't have an RTLD, we must only have a main. */
|
/* If we don't have an RTLD, we must only have a main. */
|
||||||
if (!has_nso[Nso_Rtld]) {
|
if (!has_nso[Nso_Rtld]) {
|
||||||
for (size_t i = Nso_Main + 1; i < Nso_Count; i++) {
|
for (size_t i = Nso_Main + 1; i < Nso_Count; i++) {
|
||||||
R_UNLESS(!has_nso[i], ResultInvalidNso());
|
R_UNLESS(!has_nso[i], ldr::ResultInvalidNso());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All NSOs must have zero text offset. */
|
/* All NSOs must have zero text offset. */
|
||||||
for (size_t i = 0; i < Nso_Count; i++) {
|
for (size_t i = 0; i < Nso_Count; i++) {
|
||||||
R_UNLESS(nso_headers[i].text_dst_offset == 0, ResultInvalidNso());
|
R_UNLESS(nso_headers[i].text_dst_offset == 0, ldr::ResultInvalidNso());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -222,8 +222,8 @@ namespace ams::ldr {
|
||||||
R_TRY(ValidateProgramVersion(loc.program_id, meta->npdm->version));
|
R_TRY(ValidateProgramVersion(loc.program_id, meta->npdm->version));
|
||||||
|
|
||||||
/* Validate program id. */
|
/* Validate program id. */
|
||||||
R_UNLESS(meta->aci->program_id >= meta->acid->program_id_min, ResultInvalidProgramId());
|
R_UNLESS(meta->aci->program_id >= meta->acid->program_id_min, ldr::ResultInvalidProgramId());
|
||||||
R_UNLESS(meta->aci->program_id <= meta->acid->program_id_max, ResultInvalidProgramId());
|
R_UNLESS(meta->aci->program_id <= meta->acid->program_id_max, ldr::ResultInvalidProgramId());
|
||||||
|
|
||||||
/* Validate the kernel capabilities. */
|
/* Validate the kernel capabilities. */
|
||||||
R_TRY(caps::ValidateCapabilities(meta->acid_kac, meta->acid->kac_size, meta->aci_kac, meta->aci->kac_size));
|
R_TRY(caps::ValidateCapabilities(meta->acid_kac, meta->acid->kac_size, meta->aci_kac, meta->aci->kac_size));
|
||||||
|
@ -240,7 +240,7 @@ namespace ams::ldr {
|
||||||
const size_t hsh_size = sizeof(code_verification_data.target_hash);
|
const size_t hsh_size = sizeof(code_verification_data.target_hash);
|
||||||
const bool is_signature_valid = crypto::VerifyRsa2048PssSha256WithHash(sig, sig_size, mod, mod_size, exp, exp_size, hsh, hsh_size);
|
const bool is_signature_valid = crypto::VerifyRsa2048PssSha256WithHash(sig, sig_size, mod, mod_size, exp, exp_size, hsh, hsh_size);
|
||||||
|
|
||||||
R_UNLESS(is_signature_valid, ResultInvalidNcaSignature());
|
R_UNLESS(is_signature_valid, ldr::ResultInvalidNcaSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All good. */
|
/* All good. */
|
||||||
|
@ -272,7 +272,7 @@ namespace ams::ldr {
|
||||||
flags |= svc::CreateProcessFlag_AddressSpace64Bit;
|
flags |= svc::CreateProcessFlag_AddressSpace64Bit;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ResultInvalidMeta();
|
return ldr::ResultInvalidMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Enable Debug. */
|
/* Set Enable Debug. */
|
||||||
|
@ -317,7 +317,7 @@ namespace ams::ldr {
|
||||||
flags |= svc::CreateProcessFlag_PoolPartitionSystemNonSecure;
|
flags |= svc::CreateProcessFlag_PoolPartitionSystemNonSecure;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ResultInvalidMeta();
|
return ldr::ResultInvalidMeta();
|
||||||
}
|
}
|
||||||
} else if (hos::GetVersion() >= hos::Version_4_0_0) {
|
} else if (hos::GetVersion() >= hos::Version_4_0_0) {
|
||||||
/* On 4.0.0+, the corresponding bit was simply "UseSecureMemory". */
|
/* On 4.0.0+, the corresponding bit was simply "UseSecureMemory". */
|
||||||
|
@ -351,18 +351,18 @@ namespace ams::ldr {
|
||||||
/* 3.0.0+ System Resource Size. */
|
/* 3.0.0+ System Resource Size. */
|
||||||
if (hos::GetVersion() >= hos::Version_3_0_0) {
|
if (hos::GetVersion() >= hos::Version_3_0_0) {
|
||||||
/* Validate size is aligned. */
|
/* Validate size is aligned. */
|
||||||
R_UNLESS(util::IsAligned(meta->npdm->system_resource_size, os::MemoryBlockUnitSize), ResultInvalidSize());
|
R_UNLESS(util::IsAligned(meta->npdm->system_resource_size, os::MemoryBlockUnitSize), ldr::ResultInvalidSize());
|
||||||
|
|
||||||
/* Validate system resource usage. */
|
/* Validate system resource usage. */
|
||||||
if (meta->npdm->system_resource_size) {
|
if (meta->npdm->system_resource_size) {
|
||||||
/* Process must be 64-bit. */
|
/* Process must be 64-bit. */
|
||||||
R_UNLESS((out->flags & svc::CreateProcessFlag_AddressSpace64Bit), ResultInvalidMeta());
|
R_UNLESS((out->flags & svc::CreateProcessFlag_AddressSpace64Bit), ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Process must be application or applet. */
|
/* Process must be application or applet. */
|
||||||
R_UNLESS(IsApplication(meta) || IsApplet(meta), ResultInvalidMeta());
|
R_UNLESS(IsApplication(meta) || IsApplet(meta), ldr::ResultInvalidMeta());
|
||||||
|
|
||||||
/* Size must be less than or equal to max. */
|
/* Size must be less than or equal to max. */
|
||||||
R_UNLESS(meta->npdm->system_resource_size <= SystemResourceSizeMax, ResultInvalidMeta());
|
R_UNLESS(meta->npdm->system_resource_size <= SystemResourceSizeMax, ldr::ResultInvalidMeta());
|
||||||
}
|
}
|
||||||
out->system_resource_num_pages = meta->npdm->system_resource_size >> 12;
|
out->system_resource_num_pages = meta->npdm->system_resource_size >> 12;
|
||||||
}
|
}
|
||||||
|
@ -541,19 +541,19 @@ namespace ams::ldr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate size. */
|
/* Validate size. */
|
||||||
R_UNLESS(file_size <= segment->size, ResultInvalidNso());
|
R_UNLESS(file_size <= segment->size, ldr::ResultInvalidNso());
|
||||||
R_UNLESS(segment->size <= std::numeric_limits<s32>::max(), ResultInvalidNso());
|
R_UNLESS(segment->size <= std::numeric_limits<s32>::max(), ldr::ResultInvalidNso());
|
||||||
|
|
||||||
/* Load data from file. */
|
/* Load data from file. */
|
||||||
uintptr_t load_address = is_compressed ? map_end - file_size : map_base;
|
uintptr_t load_address = is_compressed ? map_end - file_size : map_base;
|
||||||
size_t read_size;
|
size_t read_size;
|
||||||
R_TRY(fs::ReadFile(std::addressof(read_size), file, segment->file_offset, reinterpret_cast<void *>(load_address), file_size));
|
R_TRY(fs::ReadFile(std::addressof(read_size), file, segment->file_offset, reinterpret_cast<void *>(load_address), file_size));
|
||||||
R_UNLESS(read_size == file_size, ResultInvalidNso());
|
R_UNLESS(read_size == file_size, ldr::ResultInvalidNso());
|
||||||
|
|
||||||
/* Uncompress if necessary. */
|
/* Uncompress if necessary. */
|
||||||
if (is_compressed) {
|
if (is_compressed) {
|
||||||
bool decompressed = (util::DecompressLZ4(reinterpret_cast<void *>(map_base), segment->size, reinterpret_cast<const void *>(load_address), file_size) == static_cast<int>(segment->size));
|
bool decompressed = (util::DecompressLZ4(reinterpret_cast<void *>(map_base), segment->size, reinterpret_cast<const void *>(load_address), file_size) == static_cast<int>(segment->size));
|
||||||
R_UNLESS(decompressed, ResultInvalidNso());
|
R_UNLESS(decompressed, ldr::ResultInvalidNso());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check hash if necessary. */
|
/* Check hash if necessary. */
|
||||||
|
@ -561,7 +561,7 @@ namespace ams::ldr {
|
||||||
u8 hash[crypto::Sha256Generator::HashSize];
|
u8 hash[crypto::Sha256Generator::HashSize];
|
||||||
crypto::GenerateSha256Hash(hash, sizeof(hash), reinterpret_cast<void *>(map_base), segment->size);
|
crypto::GenerateSha256Hash(hash, sizeof(hash), reinterpret_cast<void *>(map_base), segment->size);
|
||||||
|
|
||||||
R_UNLESS(std::memcmp(hash, file_hash, sizeof(hash)) == 0, ResultInvalidNso());
|
R_UNLESS(std::memcmp(hash, file_hash, sizeof(hash)) == 0, ldr::ResultInvalidNso());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
|
Loading…
Reference in a new issue