From 6e5c0bde51d0ea49ed15d39bf41f593c91340ee2 Mon Sep 17 00:00:00 2001 From: Adubbz Date: Tue, 6 Aug 2019 14:13:15 +1000 Subject: [PATCH] Prevent automatic placeholder creation on open --- stratosphere/ncm/source/debug.cpp | 2 +- .../source/impl/ncm_placeholder_accessor.cpp | 7 +--- .../ncm/source/ncm_contentmetadatabase.cpp | 3 ++ .../ncm/source/ncm_contentstorage.cpp | 21 ++++------- stratosphere/ncm/source/ncm_fs.cpp | 37 +++++++++++++++++++ stratosphere/ncm/source/ncm_fs.hpp | 1 + .../ncm/source/ncm_readonlycontentstorage.cpp | 8 ++-- 7 files changed, 55 insertions(+), 24 deletions(-) diff --git a/stratosphere/ncm/source/debug.cpp b/stratosphere/ncm/source/debug.cpp index 6659ae10f..2de47244b 100644 --- a/stratosphere/ncm/source/debug.cpp +++ b/stratosphere/ncm/source/debug.cpp @@ -23,7 +23,7 @@ namespace sts::debug { } size_t g_curr_log_offset = 0; - size_t g_log_skip = 4; + size_t g_log_skip = 1000; char __attribute__ ((aligned (0x1000))) g_work_page[0x1000]; diff --git a/stratosphere/ncm/source/impl/ncm_placeholder_accessor.cpp b/stratosphere/ncm/source/impl/ncm_placeholder_accessor.cpp index 60a424a1f..f209052fc 100644 --- a/stratosphere/ncm/source/impl/ncm_placeholder_accessor.cpp +++ b/stratosphere/ncm/source/impl/ncm_placeholder_accessor.cpp @@ -100,12 +100,9 @@ namespace sts::ncm::impl { char placeholder_path[FS_MAX_PATH] = {0}; this->GetPlaceHolderPath(placeholder_path, placeholder_id); - FILE* f = fopen(placeholder_path, "r+b"); - if (f == nullptr) { - debug::DebugLog("Failed to open placeholder %s\n", placeholder_path); - return fsdevGetLastResult(); - } + FILE* f = nullptr; + R_TRY(OpenFile(&f, placeholder_path, FS_OPEN_WRITE)); *out_handle = f; return ResultSuccess; diff --git a/stratosphere/ncm/source/ncm_contentmetadatabase.cpp b/stratosphere/ncm/source/ncm_contentmetadatabase.cpp index 4aca8bac1..42110b74f 100644 --- a/stratosphere/ncm/source/ncm_contentmetadatabase.cpp +++ b/stratosphere/ncm/source/ncm_contentmetadatabase.cpp @@ -95,6 +95,8 @@ namespace sts::ncm { Result ContentMetaDatabaseInterface::GetContentIdByTypeImpl(ContentId* out, const ContentMetaKey& key, ContentType type, std::optional id_offset) { R_TRY(this->EnsureEnabled()); + D_LOG("key: 0x%lx\n", key.id); + const auto it = this->kvs->lower_bound(key); if (it == this->kvs->end() || it->GetKey().id != key.id) { return ResultNcmContentMetaNotFound; @@ -384,6 +386,7 @@ namespace sts::ncm { out.SetValue(has); return ResultSuccess; + debug::DebugLog("Has 0x%lx\n", key.id); R_DEBUG_END } diff --git a/stratosphere/ncm/source/ncm_contentstorage.cpp b/stratosphere/ncm/source/ncm_contentstorage.cpp index 0c8ad80c2..6934dd65a 100644 --- a/stratosphere/ncm/source/ncm_contentstorage.cpp +++ b/stratosphere/ncm/source/ncm_contentstorage.cpp @@ -82,15 +82,12 @@ namespace sts::ncm { this->ClearContentCache(); char content_path[FS_MAX_PATH] = {0}; this->GetContentPath(content_path, content_id); - this->content_cache_file_handle = fopen(content_path, "rb"); - if (this->content_cache_file_handle == NULL) { - R_TRY_CATCH(fsdevGetLastResult()) { - R_CATCH(ResultFsPathNotFound) { - return ResultNcmContentNotFound; - } - } R_END_TRY_CATCH; - } + R_TRY_CATCH(OpenFile(&this->content_cache_file_handle, content_path, FS_OPEN_READ)) { + R_CATCH(ResultFsPathNotFound) { + return ResultNcmContentNotFound; + } + } R_END_TRY_CATCH; this->cached_content_id = content_id; return ResultSuccess; @@ -624,15 +621,13 @@ namespace sts::ncm { char content_path[FS_MAX_PATH] = {0}; this->GetContentPath(content_path, content_id); - FILE* f = fopen(content_path, "r+b"); + FILE* f = nullptr; + R_TRY(OpenFile(&f, content_path, FS_OPEN_WRITE)); + ON_SCOPE_EXIT { fclose(f); }; - if (f == nullptr) { - return fsdevGetLastResult(); - } - if (fseek(f, offset, SEEK_SET) != 0) { return fsdevGetLastResult(); } diff --git a/stratosphere/ncm/source/ncm_fs.cpp b/stratosphere/ncm/source/ncm_fs.cpp index 908f13e43..80b3c37a8 100644 --- a/stratosphere/ncm/source/ncm_fs.cpp +++ b/stratosphere/ncm/source/ncm_fs.cpp @@ -15,12 +15,49 @@ */ #include +#include +#include #include "ncm_fs.hpp" #include "ncm_path_utils.hpp" namespace sts::ncm { + Result OpenFile(FILE** out, const char* path, u32 mode) { + bool has = false; + + /* Manually check if the file already exists, so it doesn't get created automatically. */ + R_TRY(HasFile(&has, path)); + if (!has) { + return ResultFsPathNotFound; + } + + const char* fopen_mode = ""; + + if (mode & FS_OPEN_APPEND) { + if (mode & FS_OPEN_READ) { + fopen_mode = "r+b"; + } else if (mode & FS_OPEN_WRITE) { + fopen_mode = "w+b"; + } + } else { + if (mode & FS_OPEN_READ) { + fopen_mode = "rb"; + } else if (mode & FS_OPEN_WRITE) { + fopen_mode = "wb"; + } + } + + FILE* f = fopen(path, fopen_mode); + + if (f == nullptr) { + return fsdevGetLastResult(); + } + + *out = f; + return ResultSuccess; + } + Result HasFile(bool* out, const char* path) { struct stat st; diff --git a/stratosphere/ncm/source/ncm_fs.hpp b/stratosphere/ncm/source/ncm_fs.hpp index 82cc6c5de..b5af99768 100644 --- a/stratosphere/ncm/source/ncm_fs.hpp +++ b/stratosphere/ncm/source/ncm_fs.hpp @@ -23,6 +23,7 @@ namespace sts::ncm { + Result OpenFile(FILE** out, const char* path, u32 mode); Result HasFile(bool* out, const char* path); Result HasDirectory(bool* out, const char* path); diff --git a/stratosphere/ncm/source/ncm_readonlycontentstorage.cpp b/stratosphere/ncm/source/ncm_readonlycontentstorage.cpp index dc4484c63..ef4c26452 100644 --- a/stratosphere/ncm/source/ncm_readonlycontentstorage.cpp +++ b/stratosphere/ncm/source/ncm_readonlycontentstorage.cpp @@ -224,14 +224,12 @@ namespace sts::ncm { path::GetContentMetaPath(content_path, content_id, this->make_content_path_func, this->root_path); } - FILE* f = fopen(content_path, "rb"); + FILE* f = nullptr; + R_TRY(OpenFile(&f, content_path, FS_OPEN_READ)); + ON_SCOPE_EXIT { fclose(f); }; - - if (f == nullptr) { - return fsdevGetLastResult(); - } if (fseek(f, offset, SEEK_SET) != 0) { return fsdevGetLastResult();