mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-13 20:52:15 +02:00
ncm: Use PathString and Path
This commit is contained in:
parent
cdf0445982
commit
4e29d98e22
@ -39,4 +39,7 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
using PathString = kvdb::BoundedString<fs::EntryNameLengthMax>;
|
using PathString = kvdb::BoundedString<fs::EntryNameLengthMax>;
|
||||||
|
|
||||||
|
using MakeContentPathFunc = void (*)(PathString *out, ContentId content_id, const PathString &root);
|
||||||
|
using MakePlaceHolderPathFunc = void (*)(PathString *out, PlaceHolderId placeholder_id, const PathString &root);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,6 @@ namespace ams::ncm {
|
|||||||
static_assert(sizeof(std::is_pod<ContentInfo>::value));
|
static_assert(sizeof(std::is_pod<ContentInfo>::value));
|
||||||
static_assert(sizeof(ContentInfo) == 0x18);
|
static_assert(sizeof(ContentInfo) == 0x18);
|
||||||
|
|
||||||
using MakeContentPathFunc = void (*)(char *out, ContentId content_id, const char *root);
|
|
||||||
using MakePlaceHolderPathFunc = void (*)(char *out, PlaceHolderId placeholder_id, const char *root);
|
|
||||||
|
|
||||||
/* Storage IDs. */
|
/* Storage IDs. */
|
||||||
enum class StorageId : u8 {
|
enum class StorageId : u8 {
|
||||||
#define DEFINE_ENUM_MEMBER(nm) nm = NcmStorageId_##nm
|
#define DEFINE_ENUM_MEMBER(nm) nm = NcmStorageId_##nm
|
||||||
|
@ -35,8 +35,8 @@ namespace ams::ncm::impl {
|
|||||||
|
|
||||||
Result PlaceHolderAccessor::Open(FILE** out_handle, PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::Open(FILE** out_handle, PlaceHolderId placeholder_id) {
|
||||||
R_UNLESS(!this->LoadFromCache(out_handle, placeholder_id), ResultSuccess());
|
R_UNLESS(!this->LoadFromCache(out_handle, placeholder_id), ResultSuccess());
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
this->MakePath(placeholder_path, placeholder_id);
|
this->MakePath(std::addressof(placeholder_path), placeholder_id);
|
||||||
|
|
||||||
FILE *f = nullptr;
|
FILE *f = nullptr;
|
||||||
R_TRY(fs::OpenFile(&f, placeholder_path, FsOpenMode_Write));
|
R_TRY(fs::OpenFile(&f, placeholder_path, FsOpenMode_Write));
|
||||||
@ -102,8 +102,8 @@ namespace ams::ncm::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaceHolderAccessor::Initialize(char *root, MakePlaceHolderPathFunc path_func, bool delay_flush) {
|
void PlaceHolderAccessor::Initialize(const char *root, MakePlaceHolderPathFunc path_func, bool delay_flush) {
|
||||||
this->root_path = root;
|
this->root_path = PathString(root);
|
||||||
this->make_placeholder_path_func = path_func;
|
this->make_placeholder_path_func = path_func;
|
||||||
this->delay_flush = delay_flush;
|
this->delay_flush = delay_flush;
|
||||||
}
|
}
|
||||||
@ -116,20 +116,22 @@ namespace ams::ncm::impl {
|
|||||||
} else {
|
} else {
|
||||||
AMS_ABORT();
|
AMS_ABORT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaceHolderAccessor::GetPath(char *placeholder_path_out, PlaceHolderId placeholder_id) {
|
void PlaceHolderAccessor::GetPath(PathString *placeholder_path, PlaceHolderId placeholder_id) {
|
||||||
std::scoped_lock lock(this->cache_mutex);
|
std::scoped_lock lock(this->cache_mutex);
|
||||||
CacheEntry *entry = this->FindInCache(placeholder_id);
|
CacheEntry *entry = this->FindInCache(placeholder_id);
|
||||||
this->Invalidate(entry);
|
this->Invalidate(entry);
|
||||||
this->MakePath(placeholder_path_out, placeholder_id);
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Create(PlaceHolderId placeholder_id, size_t size) {
|
Result PlaceHolderAccessor::Create(PlaceHolderId placeholder_id, size_t size) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
|
||||||
|
|
||||||
this->EnsureRecursively(placeholder_id);
|
this->EnsureRecursively(placeholder_id);
|
||||||
this->GetPath(placeholder_path, placeholder_id);
|
|
||||||
|
PathString placeholder_path;
|
||||||
|
this->GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
|
|
||||||
R_TRY_CATCH(fsdevCreateFile(placeholder_path, size, FsCreateOption_BigFile)) {
|
R_TRY_CATCH(fsdevCreateFile(placeholder_path, size, FsCreateOption_BigFile)) {
|
||||||
R_CONVERT(ams::fs::ResultPathAlreadyExists, ncm::ResultPlaceHolderAlreadyExists())
|
R_CONVERT(ams::fs::ResultPathAlreadyExists, ncm::ResultPlaceHolderAlreadyExists())
|
||||||
@ -139,11 +141,10 @@ namespace ams::ncm::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Delete(PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::Delete(PlaceHolderId placeholder_id) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
|
this->GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
|
|
||||||
this->GetPath(placeholder_path, placeholder_id);
|
|
||||||
R_UNLESS(std::remove(placeholder_path) == 0, ConvertNotFoundResult(fsdevGetLastResult()));
|
R_UNLESS(std::remove(placeholder_path) == 0, ConvertNotFoundResult(fsdevGetLastResult()));
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,10 +159,10 @@ namespace ams::ncm::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::SetSize(PlaceHolderId placeholder_id, size_t size) {
|
Result PlaceHolderAccessor::SetSize(PlaceHolderId placeholder_id, size_t size) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
this->MakePath(placeholder_path, placeholder_id);
|
this->MakePath(std::addressof(placeholder_path), placeholder_id);
|
||||||
R_UNLESS(truncate(placeholder_path, size) != -1, ConvertNotFoundResult(fsdevGetLastResult()));
|
|
||||||
|
|
||||||
|
R_UNLESS(truncate(placeholder_path, size) != -1, ConvertNotFoundResult(fsdevGetLastResult()));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +199,8 @@ namespace ams::ncm::impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::EnsureRecursively(PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::EnsureRecursively(PlaceHolderId placeholder_id) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
this->MakePath(placeholder_path, placeholder_id);
|
this->MakePath(std::addressof(placeholder_path), placeholder_id);
|
||||||
R_TRY(fs::EnsureParentDirectoryRecursively(placeholder_path));
|
R_TRY(fs::EnsureParentDirectoryRecursively(placeholder_path));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ namespace ams::ncm::impl {
|
|||||||
static constexpr size_t MaxCaches = 0x2;
|
static constexpr size_t MaxCaches = 0x2;
|
||||||
|
|
||||||
std::array<CacheEntry, MaxCaches> caches;
|
std::array<CacheEntry, MaxCaches> caches;
|
||||||
char *root_path;
|
PathString root_path;
|
||||||
u64 cur_counter;
|
u64 cur_counter;
|
||||||
os::Mutex cache_mutex;
|
os::Mutex cache_mutex;
|
||||||
MakePlaceHolderPathFunc make_placeholder_path_func;
|
MakePlaceHolderPathFunc make_placeholder_path_func;
|
||||||
@ -53,19 +53,19 @@ namespace ams::ncm::impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MakeRootPath(char *out_placeholder_root) {
|
inline void MakeRootPath(PathString *placeholder_root) {
|
||||||
path::GetPlaceHolderRootPath(out_placeholder_root, this->root_path);
|
path::GetPlaceHolderRootPath(placeholder_root, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MakePath(char *out_placeholder_path, PlaceHolderId placeholder_id) {
|
inline void MakePath(PathString *placeholder_path, PlaceHolderId placeholder_id) {
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
PathString root_path;
|
||||||
this->MakeRootPath(placeholder_root_path);
|
this->MakeRootPath(std::addressof(root_path));
|
||||||
this->make_placeholder_path_func(out_placeholder_path, placeholder_id, placeholder_root_path);
|
this->make_placeholder_path_func(placeholder_path, placeholder_id, root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(char *root, MakePlaceHolderPathFunc path_func, bool delay_flush);
|
void Initialize(const char *root, MakePlaceHolderPathFunc path_func, bool delay_flush);
|
||||||
unsigned int GetDirectoryDepth();
|
unsigned int GetDirectoryDepth();
|
||||||
void GetPath(char *out_placeholder_path, PlaceHolderId placeholder_id);
|
void GetPath(PathString *out_placeholder_path, PlaceHolderId placeholder_id);
|
||||||
Result Create(PlaceHolderId placeholder_id, size_t size);
|
Result Create(PlaceHolderId placeholder_id, size_t size);
|
||||||
Result Delete(PlaceHolderId placeholder_id);
|
Result Delete(PlaceHolderId placeholder_id);
|
||||||
Result Write(PlaceHolderId placeholder_id, size_t offset, const void *buffer, size_t size);
|
Result Write(PlaceHolderId placeholder_id, size_t offset, const void *buffer, size_t size);
|
||||||
|
@ -25,14 +25,11 @@ namespace ams::ncm {
|
|||||||
this->Finalize();
|
this->Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageImpl::Initialize(const char *root_path, MakeContentPathFunc content_path_func, MakePlaceHolderPathFunc placeholder_path_func, bool delay_flush, impl::RightsIdCache *rights_id_cache) {
|
Result ContentStorageImpl::Initialize(const char *path, MakeContentPathFunc content_path_func, MakePlaceHolderPathFunc placeholder_path_func, bool delay_flush, impl::RightsIdCache *rights_id_cache) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
R_TRY(fs::CheckContentStorageDirectoriesExist(root_path));
|
R_TRY(fs::CheckContentStorageDirectoriesExist(path));
|
||||||
const size_t root_path_len = strnlen(root_path, ams::fs::EntryNameLengthMax);
|
|
||||||
|
|
||||||
AMS_ABORT_UNLESS(root_path_len < ams::fs::EntryNameLengthMax);
|
this->root_path = PathString(path);
|
||||||
|
|
||||||
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
|
||||||
this->make_content_path_func = *content_path_func;
|
this->make_content_path_func = *content_path_func;
|
||||||
this->placeholder_accessor.Initialize(this->root_path, *placeholder_path_func, delay_flush);
|
this->placeholder_accessor.Initialize(this->root_path, *placeholder_path_func, delay_flush);
|
||||||
this->rights_id_cache = rights_id_cache;
|
this->rights_id_cache = rights_id_cache;
|
||||||
@ -69,8 +66,9 @@ namespace ams::ncm {
|
|||||||
R_UNLESS(this->cached_content_id != content_id, ResultSuccess());
|
R_UNLESS(this->cached_content_id != content_id, ResultSuccess());
|
||||||
|
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
|
||||||
this->GetContentPath(content_path, content_id);
|
PathString content_path;
|
||||||
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
|
|
||||||
R_TRY_CATCH(fs::OpenFile(&this->content_cache_file_handle, content_path, FsOpenMode_Read)) {
|
R_TRY_CATCH(fs::OpenFile(&this->content_cache_file_handle, content_path, FsOpenMode_Read)) {
|
||||||
R_CONVERT(ams::fs::ResultPathNotFound, ncm::ResultContentNotFound())
|
R_CONVERT(ams::fs::ResultPathNotFound, ncm::ResultContentNotFound())
|
||||||
@ -89,8 +87,8 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
Result ContentStorageImpl::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, u64 size) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
|
|
||||||
R_TRY(fs::EnsureParentDirectoryRecursively(content_path));
|
R_TRY(fs::EnsureParentDirectoryRecursively(content_path));
|
||||||
R_TRY(this->placeholder_accessor.Create(placeholder_id, size));
|
R_TRY(this->placeholder_accessor.Create(placeholder_id, size));
|
||||||
@ -106,8 +104,8 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) {
|
Result ContentStorageImpl::HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
this->placeholder_accessor.MakePath(placeholder_path, placeholder_id);
|
this->placeholder_accessor.MakePath(std::addressof(placeholder_path), placeholder_id);
|
||||||
|
|
||||||
bool has = false;
|
bool has = false;
|
||||||
R_TRY(fs::HasFile(&has, placeholder_path));
|
R_TRY(fs::HasFile(&has, placeholder_path));
|
||||||
@ -128,11 +126,10 @@ namespace ams::ncm {
|
|||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
|
this->placeholder_accessor.GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
this->GetContentPath(content_path, content_id);
|
|
||||||
|
|
||||||
if (rename(placeholder_path, content_path) != 0) {
|
if (rename(placeholder_path, content_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
@ -148,8 +145,9 @@ namespace ams::ncm {
|
|||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
|
||||||
this->GetContentPath(content_path, content_id);
|
PathString content_path;
|
||||||
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
|
|
||||||
if (std::remove(content_path) != 0) {
|
if (std::remove(content_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
@ -163,8 +161,8 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::Has(sf::Out<bool> out, ContentId content_id) {
|
Result ContentStorageImpl::Has(sf::Out<bool> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
|
|
||||||
bool has = false;
|
bool has = false;
|
||||||
R_TRY(fs::HasFile(&has, content_path));
|
R_TRY(fs::HasFile(&has, content_path));
|
||||||
@ -176,31 +174,33 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::GetPath(sf::Out<Path> out, ContentId content_id) {
|
Result ContentStorageImpl::GetPath(sf::Out<Path> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
this->GetContentPath(content_path, content_id);
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, content_path));
|
Path common_path;
|
||||||
out.SetValue(Path::Encode(common_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, content_path));
|
||||||
|
out.SetValue(Path::Encode(common_path.str));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageImpl::GetPlaceHolderPath(sf::Out<Path> out, PlaceHolderId placeholder_id) {
|
Result ContentStorageImpl::GetPlaceHolderPath(sf::Out<Path> out, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
this->placeholder_accessor.GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, placeholder_path));
|
Path common_path;
|
||||||
out.SetValue(Path::Encode(common_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, placeholder_path));
|
||||||
|
out.SetValue(Path::Encode(common_path.str));
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageImpl::CleanupAllPlaceHolder() {
|
Result ContentStorageImpl::CleanupAllPlaceHolder() {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
PathString placeholder_root_path;
|
||||||
this->placeholder_accessor.InvalidateAll();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
this->placeholder_accessor.MakeRootPath(placeholder_root_path);
|
this->placeholder_accessor.MakeRootPath(std::addressof(placeholder_root_path));
|
||||||
|
|
||||||
/* Nintendo uses CleanDirectoryRecursively which is 3.0.0+.
|
/* Nintendo uses CleanDirectoryRecursively which is 3.0.0+.
|
||||||
We'll just delete the directory and recreate it to support all firmwares. */
|
We'll just delete the directory and recreate it to support all firmwares. */
|
||||||
@ -212,8 +212,8 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) {
|
Result ContentStorageImpl::ListPlaceHolder(sf::Out<u32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
PathString placeholder_root_path;
|
||||||
this->placeholder_accessor.MakeRootPath(placeholder_root_path);
|
this->placeholder_accessor.MakeRootPath(std::addressof(placeholder_root_path));
|
||||||
const unsigned int dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
const unsigned int dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
||||||
size_t entry_count = 0;
|
size_t entry_count = 0;
|
||||||
|
|
||||||
@ -239,8 +239,8 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::GetContentCount(sf::Out<u32> out_count) {
|
Result ContentStorageImpl::GetContentCount(sf::Out<u32> out_count) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_root_path[FS_MAX_PATH] = {0};
|
PathString content_root_path;
|
||||||
this->GetContentRootPath(content_root_path);
|
this->GetContentRootPath(std::addressof(content_root_path));
|
||||||
const unsigned int dir_depth = this->GetContentDirectoryDepth();
|
const unsigned int dir_depth = this->GetContentDirectoryDepth();
|
||||||
u32 content_count = 0;
|
u32 content_count = 0;
|
||||||
|
|
||||||
@ -263,8 +263,9 @@ namespace ams::ncm {
|
|||||||
R_UNLESS(start_offset <= std::numeric_limits<s32>::max(), ncm::ResultInvalidOffset());
|
R_UNLESS(start_offset <= std::numeric_limits<s32>::max(), ncm::ResultInvalidOffset());
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_root_path[FS_MAX_PATH] = {0};
|
PathString content_root_path;
|
||||||
this->GetContentRootPath(content_root_path);
|
this->GetContentRootPath(std::addressof(content_root_path));
|
||||||
|
|
||||||
const unsigned int dir_depth = this->GetContentDirectoryDepth();
|
const unsigned int dir_depth = this->GetContentDirectoryDepth();
|
||||||
size_t entry_count = 0;
|
size_t entry_count = 0;
|
||||||
|
|
||||||
@ -311,8 +312,8 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) {
|
Result ContentStorageImpl::GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
R_UNLESS(stat(content_path, &st) != -1, fsdevGetLastResult());
|
R_UNLESS(stat(content_path, &st) != -1, fsdevGetLastResult());
|
||||||
@ -330,18 +331,18 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
Result ContentStorageImpl::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char old_content_path[FS_MAX_PATH] = {0};
|
PathString old_content_path;
|
||||||
char new_content_path[FS_MAX_PATH] = {0};
|
PathString new_content_path;
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
|
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
|
|
||||||
/* Ensure the new content path is ready. */
|
/* Ensure the new content path is ready. */
|
||||||
this->GetContentPath(new_content_path, new_content_id);
|
this->GetContentPath(std::addressof(new_content_path), new_content_id);
|
||||||
R_TRY(fs::EnsureParentDirectoryRecursively(new_content_path));
|
R_TRY(fs::EnsureParentDirectoryRecursively(new_content_path));
|
||||||
|
|
||||||
R_TRY(this->placeholder_accessor.EnsureRecursively(placeholder_id));
|
R_TRY(this->placeholder_accessor.EnsureRecursively(placeholder_id));
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
if (rename(old_content_path, placeholder_path) != 0) {
|
if (rename(old_content_path, placeholder_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CONVERT(ams::fs::ResultPathNotFound, ncm::ResultPlaceHolderNotFound())
|
R_CONVERT(ams::fs::ResultPathNotFound, ncm::ResultPlaceHolderNotFound())
|
||||||
@ -362,8 +363,10 @@ namespace ams::ncm {
|
|||||||
/* Offset is too large */
|
/* Offset is too large */
|
||||||
R_UNLESS(offset <= std::numeric_limits<s64>::max(), ncm::ResultInvalidOffset());
|
R_UNLESS(offset <= std::numeric_limits<s64>::max(), ncm::ResultInvalidOffset());
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
|
||||||
this->GetContentPath(content_path, content_id);
|
PathString content_path;
|
||||||
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
|
|
||||||
R_TRY(this->OpenCachedContentFile(content_id));
|
R_TRY(this->OpenCachedContentFile(content_id));
|
||||||
R_TRY(fs::ReadFile(this->content_cache_file_handle, offset, buf.GetPointer(), buf.GetSize()));
|
R_TRY(fs::ReadFile(this->content_cache_file_handle, offset, buf.GetPointer(), buf.GetSize()));
|
||||||
|
|
||||||
@ -380,10 +383,11 @@ namespace ams::ncm {
|
|||||||
Result ContentStorageImpl::GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) {
|
Result ContentStorageImpl::GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
this->placeholder_accessor.GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, placeholder_path));
|
Path common_path;
|
||||||
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, placeholder_path));
|
||||||
|
|
||||||
ncm::RightsId rights_id;
|
ncm::RightsId rights_id;
|
||||||
R_TRY(GetRightsId(&rights_id, common_path));
|
R_TRY(GetRightsId(&rights_id, common_path));
|
||||||
@ -406,10 +410,11 @@ namespace ams::ncm {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
this->GetContentPath(content_path, content_id);
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, content_path));
|
Path common_path;
|
||||||
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, content_path));
|
||||||
|
|
||||||
ncm::RightsId rights_id;
|
ncm::RightsId rights_id;
|
||||||
R_TRY(GetRightsId(&rights_id, common_path));
|
R_TRY(GetRightsId(&rights_id, common_path));
|
||||||
@ -432,8 +437,8 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(std::addressof(content_path), content_id);
|
||||||
|
|
||||||
FILE *f = nullptr;
|
FILE *f = nullptr;
|
||||||
R_TRY(fs::OpenFile(&f, content_path, FsOpenMode_Write));
|
R_TRY(fs::OpenFile(&f, content_path, FsOpenMode_Write));
|
||||||
@ -479,10 +484,10 @@ namespace ams::ncm {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
R_UNLESS(stat(placeholder_path, &st) != -1, fsdevGetLastResult());
|
R_UNLESS(stat(placeholder_path, &st) != -1, fsdevGetLastResult());
|
||||||
|
|
||||||
out_size.SetValue(st.st_size);
|
out_size.SetValue(st.st_size);
|
||||||
@ -490,8 +495,8 @@ namespace ams::ncm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ContentStorageImpl::RepairInvalidFileAttribute() {
|
Result ContentStorageImpl::RepairInvalidFileAttribute() {
|
||||||
char content_root_path[FS_MAX_PATH] = {0};
|
PathString content_root_path;
|
||||||
this->GetContentRootPath(content_root_path);
|
this->GetContentRootPath(std::addressof(content_root_path));
|
||||||
unsigned int dir_depth = this->GetContentDirectoryDepth();
|
unsigned int dir_depth = this->GetContentDirectoryDepth();
|
||||||
auto fix_file_attributes = [&](bool *should_continue, bool *should_retry_dir_read, const char *current_path, struct dirent *dir_entry) {
|
auto fix_file_attributes = [&](bool *should_continue, bool *should_retry_dir_read, const char *current_path, struct dirent *dir_entry) {
|
||||||
*should_retry_dir_read = false;
|
*should_retry_dir_read = false;
|
||||||
@ -510,9 +515,9 @@ namespace ams::ncm {
|
|||||||
|
|
||||||
R_TRY(fs::TraverseDirectory(content_root_path, dir_depth, fix_file_attributes));
|
R_TRY(fs::TraverseDirectory(content_root_path, dir_depth, fix_file_attributes));
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
PathString placeholder_root_path;
|
||||||
this->placeholder_accessor.InvalidateAll();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
this->placeholder_accessor.MakeRootPath(placeholder_root_path);
|
this->placeholder_accessor.MakeRootPath(std::addressof(placeholder_root_path));
|
||||||
dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
||||||
|
|
||||||
R_TRY(fs::TraverseDirectory(placeholder_root_path, dir_depth, fix_file_attributes));
|
R_TRY(fs::TraverseDirectory(placeholder_root_path, dir_depth, fix_file_attributes));
|
||||||
@ -527,11 +532,11 @@ namespace ams::ncm {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
PathString placeholder_path;
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
this->placeholder_accessor.GetPath(std::addressof(placeholder_path), placeholder_id);
|
||||||
|
|
||||||
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
Path common_path;
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, placeholder_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, placeholder_path));
|
||||||
|
|
||||||
ncm::RightsId rights_id;
|
ncm::RightsId rights_id;
|
||||||
R_TRY(GetRightsId(&rights_id, common_path));
|
R_TRY(GetRightsId(&rights_id, common_path));
|
||||||
|
@ -41,15 +41,14 @@ namespace ams::ncm {
|
|||||||
unsigned int GetContentDirectoryDepth();
|
unsigned int GetContentDirectoryDepth();
|
||||||
Result OpenCachedContentFile(ContentId content_id);
|
Result OpenCachedContentFile(ContentId content_id);
|
||||||
|
|
||||||
inline void GetContentRootPath(char *out_content_root) {
|
inline void GetContentRootPath(PathString *content_root) {
|
||||||
path::GetContentRootPath(out_content_root, this->root_path);
|
path::GetContentRootPath(content_root, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetContentPath(char *out_content_path, ContentId content_id) {
|
inline void GetContentPath(PathString *content_path, ContentId content_id) {
|
||||||
char content_root_path[FS_MAX_PATH] = {0};
|
PathString root_path;
|
||||||
|
this->GetContentRootPath(std::addressof(root_path));
|
||||||
this->GetContentRootPath(content_root_path);
|
this->make_content_path_func(content_path, content_id, root_path);
|
||||||
this->make_content_path_func(out_content_path, content_id, content_root_path);
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) override;
|
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) override;
|
||||||
|
@ -23,7 +23,7 @@ namespace ams::ncm {
|
|||||||
NON_COPYABLE(ContentStorageImplBase);
|
NON_COPYABLE(ContentStorageImplBase);
|
||||||
NON_MOVEABLE(ContentStorageImplBase);
|
NON_MOVEABLE(ContentStorageImplBase);
|
||||||
protected:
|
protected:
|
||||||
char root_path[ams::fs::EntryNameLengthMax];
|
PathString root_path;
|
||||||
MakeContentPathFunc make_content_path_func;
|
MakeContentPathFunc make_content_path_func;
|
||||||
bool disabled;
|
bool disabled;
|
||||||
protected:
|
protected:
|
||||||
@ -34,11 +34,11 @@ namespace ams::ncm {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result GetRightsId(ncm::RightsId *out_rights_id, const char *path) {
|
static Result GetRightsId(ncm::RightsId *out_rights_id, const Path &path) {
|
||||||
if (hos::GetVersion() >= hos::Version_300) {
|
if (hos::GetVersion() >= hos::Version_300) {
|
||||||
R_TRY(ams::fs::GetRightsId(std::addressof(out_rights_id->id), std::addressof(out_rights_id->key_generation), path));
|
R_TRY(ams::fs::GetRightsId(std::addressof(out_rights_id->id), std::addressof(out_rights_id->key_generation), path.str));
|
||||||
} else {
|
} else {
|
||||||
R_TRY(ams::fs::GetRightsId(std::addressof(out_rights_id->id), path));
|
R_TRY(ams::fs::GetRightsId(std::addressof(out_rights_id->id), path.str));
|
||||||
out_rights_id->key_generation = 0;
|
out_rights_id->key_generation = 0;
|
||||||
}
|
}
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -98,20 +98,21 @@ namespace ams::ncm::fs {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CheckContentStorageDirectoriesExist(const char *root_path) {
|
Result CheckContentStorageDirectoriesExist(const char *path) {
|
||||||
char content_root[FS_MAX_PATH] = {0};
|
const PathString root_path(path);
|
||||||
char placeholder_root[FS_MAX_PATH] = {0};
|
|
||||||
|
|
||||||
bool has_root = false;
|
bool has_root = false;
|
||||||
R_TRY(HasDirectory(&has_root, root_path));
|
R_TRY(HasDirectory(&has_root, root_path));
|
||||||
R_UNLESS(has_root, ncm::ResultContentStorageBaseNotFound());
|
R_UNLESS(has_root, ncm::ResultContentStorageBaseNotFound());
|
||||||
|
|
||||||
path::GetContentRootPath(content_root, root_path);
|
PathString content_root;
|
||||||
|
path::GetContentRootPath(std::addressof(content_root), root_path);
|
||||||
bool has_content_root = false;
|
bool has_content_root = false;
|
||||||
R_TRY(HasDirectory(&has_content_root, content_root));
|
R_TRY(HasDirectory(&has_content_root, content_root));
|
||||||
R_UNLESS(has_content_root, ncm::ResultInvalidContentStorageBase());
|
R_UNLESS(has_content_root, ncm::ResultInvalidContentStorageBase());
|
||||||
|
|
||||||
path::GetPlaceHolderRootPath(placeholder_root, root_path);
|
PathString placeholder_root;
|
||||||
|
path::GetPlaceHolderRootPath(std::addressof(placeholder_root), root_path);
|
||||||
bool has_placeholder_root = false;
|
bool has_placeholder_root = false;
|
||||||
R_TRY(HasDirectory(&has_placeholder_root, placeholder_root));
|
R_TRY(HasDirectory(&has_placeholder_root, placeholder_root));
|
||||||
R_UNLESS(has_placeholder_root, ncm::ResultInvalidContentStorageBase());
|
R_UNLESS(has_placeholder_root, ncm::ResultInvalidContentStorageBase());
|
||||||
@ -119,13 +120,15 @@ namespace ams::ncm::fs {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result EnsureContentAndPlaceHolderRoot(const char *root_path) {
|
Result EnsureContentAndPlaceHolderRoot(const char *path) {
|
||||||
char content_root[FS_MAX_PATH] = {0};
|
const PathString root_path(path);
|
||||||
char placeholder_root[FS_MAX_PATH] = {0};
|
|
||||||
|
|
||||||
path::GetContentRootPath(content_root, root_path);
|
PathString content_root;
|
||||||
|
path::GetContentRootPath(std::addressof(content_root), root_path);
|
||||||
R_TRY(EnsureDirectoryRecursively(content_root));
|
R_TRY(EnsureDirectoryRecursively(content_root));
|
||||||
path::GetPlaceHolderRootPath(placeholder_root, root_path);
|
|
||||||
|
PathString placeholder_root;
|
||||||
|
path::GetPlaceHolderRootPath(std::addressof(placeholder_root), root_path);
|
||||||
R_TRY(EnsureDirectoryRecursively(placeholder_root));
|
R_TRY(EnsureDirectoryRecursively(placeholder_root));
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -35,47 +35,50 @@ namespace ams::ncm::path {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeContentPathFlat(char *path_out, ContentId content_id, const char *root) {
|
void MakeContentPathFlat(PathString *out, ContentId content_id, const PathString &root) {
|
||||||
char content_name[FS_MAX_PATH] = {0};
|
Path content_name;
|
||||||
GetContentFileName(content_name, content_id);
|
GetContentFileName(content_name.str, content_id);
|
||||||
AMS_ABORT_UNLESS(snprintf(path_out, ams::fs::EntryNameLengthMax, "%s/%s", root, content_name) >= 0);
|
out->SetFormat("%s/%s", root.Get(), content_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeContentPathDualLayered(char *path_out, ContentId content_id, const char *root) {
|
void MakeContentPathDualLayered(PathString *out, ContentId content_id, const PathString &root) {
|
||||||
char content_name[FS_MAX_PATH] = {0};
|
|
||||||
const u16 hash = Get16BitSha256HashPrefix(content_id.uuid);
|
const u16 hash = Get16BitSha256HashPrefix(content_id.uuid);
|
||||||
const u32 hash_lower = (hash >> 4) & 0x3f;
|
const u32 hash_lower = (hash >> 4) & 0x3f;
|
||||||
const u32 hash_upper = (hash >> 10) & 0x3f;
|
const u32 hash_upper = (hash >> 10) & 0x3f;
|
||||||
|
|
||||||
GetContentFileName(content_name, content_id);
|
Path content_name;
|
||||||
AMS_ABORT_UNLESS(snprintf(path_out, ams::fs::EntryNameLengthMax, "%s/%08X/%08X/%s", root, hash_upper, hash_lower, content_name) >= 0);
|
GetContentFileName(content_name.str, content_id);
|
||||||
|
out->SetFormat("%s/%08X/%08X/%s", root.Get(), hash_upper, hash_lower, content_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeContentPath10BitLayered(char *path_out, ContentId content_id, const char *root) {
|
void MakeContentPath10BitLayered(PathString *out, ContentId content_id, const PathString &root) {
|
||||||
char content_name[FS_MAX_PATH] = {0};
|
|
||||||
const u32 hash = (Get16BitSha256HashPrefix(content_id.uuid) >> 6) & 0x3FF;
|
const u32 hash = (Get16BitSha256HashPrefix(content_id.uuid) >> 6) & 0x3FF;
|
||||||
GetContentFileName(content_name, content_id);
|
|
||||||
AMS_ABORT_UNLESS(snprintf(path_out, ams::fs::EntryNameLengthMax, "%s/%08X/%s", root, hash, content_name) >= 0);
|
Path content_name;
|
||||||
|
GetContentFileName(content_name.str, content_id);
|
||||||
|
out->SetFormat("%s/%08X/%s", root.Get(), hash, content_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeContentPathHashByteLayered(char *path_out, ContentId content_id, const char *root) {
|
void MakeContentPathHashByteLayered(PathString *out, ContentId content_id, const PathString &root) {
|
||||||
char content_name[FS_MAX_PATH] = {0};
|
|
||||||
const u32 hash_byte = static_cast<u32>(Get8BitSha256HashPrefix(content_id.uuid));
|
const u32 hash_byte = static_cast<u32>(Get8BitSha256HashPrefix(content_id.uuid));
|
||||||
GetContentFileName(content_name, content_id);
|
|
||||||
AMS_ABORT_UNLESS(snprintf(path_out, ams::fs::EntryNameLengthMax, "%s/%08X/%s", root, hash_byte, content_name) >= 0);
|
Path content_name;
|
||||||
|
GetContentFileName(content_name.str, content_id);
|
||||||
|
out->SetFormat("%s/%08X/%s", root.Get(), hash_byte, content_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakePlaceHolderPathFlat(char *path_out, PlaceHolderId placeholder_id, const char *root) {
|
void MakePlaceHolderPathFlat(PathString *out, PlaceHolderId placeholder_id, const PathString &root) {
|
||||||
char placeholder_name[FS_MAX_PATH] = {0};
|
Path placeholder_name;
|
||||||
GetPlaceHolderFileName(placeholder_name, placeholder_id);
|
GetPlaceHolderFileName(placeholder_name.str, placeholder_id);
|
||||||
AMS_ABORT_UNLESS(snprintf(path_out, ams::fs::EntryNameLengthMax, "%s/%s", root, placeholder_name) >= 0);
|
out->SetFormat("%s/%s", root.Get(), placeholder_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakePlaceHolderPathHashByteLayered(char *path_out, PlaceHolderId placeholder_id, const char *root) {
|
void MakePlaceHolderPathHashByteLayered(PathString *out, PlaceHolderId placeholder_id, const PathString &root) {
|
||||||
char placeholder_name[FS_MAX_PATH] = {0};
|
|
||||||
const u32 hash_byte = static_cast<u32>(Get8BitSha256HashPrefix(placeholder_id.uuid));
|
const u32 hash_byte = static_cast<u32>(Get8BitSha256HashPrefix(placeholder_id.uuid));
|
||||||
GetPlaceHolderFileName(placeholder_name, placeholder_id);
|
|
||||||
AMS_ABORT_UNLESS(snprintf(path_out, ams::fs::EntryNameLengthMax, "%s/%08X/%s", root, hash_byte, placeholder_name) >= 0);
|
Path placeholder_name;
|
||||||
|
GetPlaceHolderFileName(placeholder_name.str, placeholder_id);
|
||||||
|
out->SetFormat("%s/%08X/%s", root.Get(), hash_byte, placeholder_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
|
|
||||||
namespace ams::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
void MakeContentPathFlat(char *out_path, ContentId content_id, const char *root);
|
void MakeContentPathFlat(PathString *out, ContentId content_id, const PathString &root);
|
||||||
void MakeContentPathHashByteLayered(char *out_path, ContentId content_id, const char *root);
|
void MakeContentPathHashByteLayered(PathString *out, ContentId content_id, const PathString &root);
|
||||||
void MakeContentPath10BitLayered(char *out_path, ContentId content_id, const char *root);
|
void MakeContentPath10BitLayered(PathString *out, ContentId content_id, const PathString &root);
|
||||||
void MakeContentPathDualLayered(char *out_path, ContentId content_id, const char *root);
|
void MakeContentPathDualLayered(PathString *out, ContentId content_id, const PathString &root);
|
||||||
|
|
||||||
void MakePlaceHolderPathFlat(char *out_path, PlaceHolderId placeholder_id, const char *root);
|
void MakePlaceHolderPathFlat(PathString *out, PlaceHolderId placeholder_id, const PathString &root);
|
||||||
void MakePlaceHolderPathHashByteLayered(char *out_path, PlaceHolderId placeholder_id, const char *root);
|
void MakePlaceHolderPathHashByteLayered(PathString *out, PlaceHolderId placeholder_id, const PathString &root);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,22 +19,12 @@
|
|||||||
|
|
||||||
namespace ams::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
void GetContentMetaPath(char *out, ContentId content_id, MakeContentPathFunc path_func, const char *root_path) {
|
void GetContentMetaPath(PathString *out, ContentId content_id, MakeContentPathFunc path_func, const PathString &root_path) {
|
||||||
char tmp_path[ams::fs::EntryNameLengthMax] = {0};
|
PathString content_path;
|
||||||
char content_path[ams::fs::EntryNameLengthMax] = {0};
|
path_func(std::addressof(content_path), content_id, root_path);
|
||||||
path_func(content_path, content_id, root_path);
|
|
||||||
const size_t len = strnlen(content_path, ams::fs::EntryNameLengthMax);
|
|
||||||
const size_t len_no_extension = len - 4;
|
|
||||||
|
|
||||||
AMS_ABORT_UNLESS(len_no_extension <= len);
|
out->Set(content_path.GetSubstring(0, content_path.GetLength() - 4));
|
||||||
AMS_ABORT_UNLESS(len_no_extension < ams::fs::EntryNameLengthMax);
|
out->Append(".cnmt.nca");
|
||||||
|
|
||||||
strncpy(tmp_path, content_path, len_no_extension);
|
|
||||||
memcpy(out, tmp_path, ams::fs::EntryNameLengthMax);
|
|
||||||
const size_t out_len = strnlen(out, ams::fs::EntryNameLengthMax);
|
|
||||||
|
|
||||||
AMS_ABORT_UNLESS(out_len + 9 < ams::fs::EntryNameLengthMax);
|
|
||||||
strncat(out, ".cnmt.nca", 0x2ff - out_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetContentFileName(char *out, ContentId content_id) {
|
void GetContentFileName(char *out, ContentId content_id) {
|
||||||
|
@ -20,17 +20,15 @@
|
|||||||
|
|
||||||
namespace ams::ncm::path {
|
namespace ams::ncm::path {
|
||||||
|
|
||||||
inline void GetContentRootPath(char *out_content_root, const char *root_path) {
|
inline void GetContentRootPath(PathString *content_root, const PathString &root_path) {
|
||||||
/* TODO: Replace with BoundedString? */
|
content_root->SetFormat("%s%s", root_path.Get(), "/registered");
|
||||||
AMS_ABORT_UNLESS(snprintf(out_content_root, ams::fs::EntryNameLengthMax, "%s%s", root_path, "/registered") >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetPlaceHolderRootPath(char *out_placeholder_root, const char *root_path) {
|
inline void GetPlaceHolderRootPath(PathString *placeholder_root, const PathString &root_path) {
|
||||||
/* TODO: Replace with BoundedString? */
|
placeholder_root->SetFormat("%s%s", root_path.Get(), "/placehld");
|
||||||
AMS_ABORT_UNLESS(snprintf(out_placeholder_root, FS_MAX_PATH, "%s%s", root_path, "/placehld") >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetContentMetaPath(char *out, ContentId content_id, MakeContentPathFunc path_func, const char *root_path);
|
void GetContentMetaPath(PathString *out, ContentId content_id, MakeContentPathFunc path_func, const PathString &root_path);
|
||||||
void GetContentFileName(char *out, ContentId content_id);
|
void GetContentFileName(char *out, ContentId content_id);
|
||||||
void GetPlaceHolderFileName(char *out, PlaceHolderId placeholder_id);
|
void GetPlaceHolderFileName(char *out, PlaceHolderId placeholder_id);
|
||||||
bool IsNcaPath(const char *path);
|
bool IsNcaPath(const char *path);
|
||||||
|
@ -20,12 +20,10 @@
|
|||||||
|
|
||||||
namespace ams::ncm {
|
namespace ams::ncm {
|
||||||
|
|
||||||
Result ReadOnlyContentStorageImpl::Initialize(const char *root_path, MakeContentPathFunc content_path_func) {
|
Result ReadOnlyContentStorageImpl::Initialize(const char *path, MakeContentPathFunc content_path_func) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
const size_t root_path_len = strnlen(root_path, ams::fs::EntryNameLengthMax);
|
this->root_path = PathString(path);
|
||||||
AMS_ABORT_UNLESS(root_path_len < ams::fs::EntryNameLengthMax);
|
|
||||||
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
|
||||||
this->make_content_path_func = *content_path_func;
|
this->make_content_path_func = *content_path_func;
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
@ -61,14 +59,14 @@ namespace ams::ncm {
|
|||||||
Result ReadOnlyContentStorageImpl::Has(sf::Out<bool> out, ContentId content_id) {
|
Result ReadOnlyContentStorageImpl::Has(sf::Out<bool> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
this->make_content_path_func(content_path, content_id, this->root_path);
|
this->make_content_path_func(std::addressof(content_path), content_id, this->root_path);
|
||||||
|
|
||||||
bool has = false;
|
bool has = false;
|
||||||
R_TRY(fs::HasFile(&has, content_path));
|
R_TRY(fs::HasFile(&has, content_path));
|
||||||
|
|
||||||
if (!has) {
|
if (!has) {
|
||||||
path::GetContentMetaPath(content_path, content_id, this->make_content_path_func, this->root_path);
|
path::GetContentMetaPath(std::addressof(content_path), content_id, this->make_content_path_func, this->root_path);
|
||||||
R_TRY(fs::HasFile(&has, content_path));
|
R_TRY(fs::HasFile(&has, content_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,19 +77,19 @@ namespace ams::ncm {
|
|||||||
Result ReadOnlyContentStorageImpl::GetPath(sf::Out<Path> out, ContentId content_id) {
|
Result ReadOnlyContentStorageImpl::GetPath(sf::Out<Path> out, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
path::GetContentMetaPath(std::addressof(content_path), content_id, this->make_content_path_func, this->root_path);
|
||||||
|
|
||||||
bool is_content_meta_file = false;
|
bool is_content_meta_file = false;
|
||||||
|
|
||||||
path::GetContentMetaPath(content_path, content_id, this->make_content_path_func, this->root_path);
|
|
||||||
R_TRY(fs::HasFile(&is_content_meta_file, content_path));
|
R_TRY(fs::HasFile(&is_content_meta_file, content_path));
|
||||||
|
|
||||||
if (!is_content_meta_file) {
|
if (!is_content_meta_file) {
|
||||||
this->make_content_path_func(content_path, content_id, this->root_path);
|
this->make_content_path_func(std::addressof(content_path), content_id, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, content_path));
|
Path common_path;
|
||||||
out.SetValue(Path::Encode(common_path));
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, content_path));
|
||||||
|
out.SetValue(Path::Encode(common_path.str));
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
@ -119,14 +117,14 @@ namespace ams::ncm {
|
|||||||
Result ReadOnlyContentStorageImpl::GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) {
|
Result ReadOnlyContentStorageImpl::GetSizeFromContentId(sf::Out<u64> out_size, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
bool is_content_file = false;
|
this->make_content_path_func(std::addressof(content_path), content_id, this->root_path);
|
||||||
|
|
||||||
this->make_content_path_func(content_path, content_id, this->root_path);
|
bool is_content_file = false;
|
||||||
R_TRY(fs::HasFile(&is_content_file, content_path));
|
R_TRY(fs::HasFile(&is_content_file, content_path));
|
||||||
|
|
||||||
if (!is_content_file) {
|
if (!is_content_file) {
|
||||||
path::GetContentMetaPath(content_path, content_id, this->make_content_path_func, this->root_path);
|
path::GetContentMetaPath(std::addressof(content_path), content_id, this->make_content_path_func, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -153,14 +151,14 @@ namespace ams::ncm {
|
|||||||
R_UNLESS(offset <= std::numeric_limits<s64>::max(), ncm::ResultInvalidOffset());
|
R_UNLESS(offset <= std::numeric_limits<s64>::max(), ncm::ResultInvalidOffset());
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
bool is_content_file = false;
|
this->make_content_path_func(std::addressof(content_path), content_id, this->root_path);
|
||||||
|
|
||||||
this->make_content_path_func(content_path, content_id, this->root_path);
|
bool is_content_file = false;
|
||||||
R_TRY(fs::HasFile(&is_content_file, content_path));
|
R_TRY(fs::HasFile(&is_content_file, content_path));
|
||||||
|
|
||||||
if (!is_content_file) {
|
if (!is_content_file) {
|
||||||
path::GetContentMetaPath(content_path, content_id, this->make_content_path_func, this->root_path);
|
path::GetContentMetaPath(std::addressof(content_path), content_id, this->make_content_path_func, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *f = nullptr;
|
FILE *f = nullptr;
|
||||||
@ -192,18 +190,18 @@ namespace ams::ncm {
|
|||||||
Result ReadOnlyContentStorageImpl::GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) {
|
Result ReadOnlyContentStorageImpl::GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
PathString content_path;
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
path::GetContentMetaPath(std::addressof(content_path), content_id, this->make_content_path_func, this->root_path);
|
||||||
bool is_content_meta_file = false;
|
|
||||||
|
|
||||||
path::GetContentMetaPath(content_path, content_id, this->make_content_path_func, this->root_path);
|
bool is_content_meta_file = false;
|
||||||
R_TRY(fs::HasFile(&is_content_meta_file, content_path));
|
R_TRY(fs::HasFile(&is_content_meta_file, content_path));
|
||||||
|
|
||||||
if (!is_content_meta_file) {
|
if (!is_content_meta_file) {
|
||||||
this->make_content_path_func(content_path, content_id, this->root_path);
|
this->make_content_path_func(std::addressof(content_path), content_id, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(fs::ConvertToFsCommonPath(common_path, ams::fs::EntryNameLengthMax, content_path));
|
Path common_path;
|
||||||
|
R_TRY(fs::ConvertToFsCommonPath(common_path.str, ams::fs::EntryNameLengthMax, content_path));
|
||||||
|
|
||||||
ncm::RightsId rights_id;
|
ncm::RightsId rights_id;
|
||||||
R_TRY(GetRightsId(&rights_id, common_path));
|
R_TRY(GetRightsId(&rights_id, common_path));
|
||||||
|
Loading…
Reference in New Issue
Block a user