warn if cia contend is encrypted
This commit is contained in:
parent
ad3c464e2d
commit
ae4ba287d5
4 changed files with 84 additions and 4 deletions
|
@ -47,12 +47,16 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
|||
if (!is_dir && HasSupportedFileExtension(physical_name)) {
|
||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name);
|
||||
if (!loader)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool executable = false;
|
||||
loader->IsExecutable(executable);
|
||||
if (!executable)
|
||||
auto res = loader->IsExecutable(executable);
|
||||
if (!executable && res != Loader::ResultStatus::ErrorEncrypted)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 program_id = 0;
|
||||
loader->ReadProgramId(program_id);
|
||||
|
|
|
@ -133,8 +133,37 @@ Loader::ResultStatus NCCHContainer::OpenFile(const std::string& filepath, u32 nc
|
|||
return Loader::ResultStatus::Success;
|
||||
}
|
||||
|
||||
Loader::ResultStatus NCCHContainer::LoadHeader() {
|
||||
if (has_header)
|
||||
return Loader::ResultStatus::Success;
|
||||
if (!file.IsOpen()) {
|
||||
|
||||
return Loader::ResultStatus::Error;
|
||||
}
|
||||
|
||||
// Reset read pointer in case this file has been read before.
|
||||
file.Seek(ncch_offset, SEEK_SET);
|
||||
|
||||
if (file.ReadBytes(&ncch_header, sizeof(NCCH_Header)) != sizeof(NCCH_Header))
|
||||
return Loader::ResultStatus::Error;
|
||||
|
||||
// Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)...
|
||||
if (Loader::MakeMagic('N', 'C', 'S', 'D') == ncch_header.magic) {
|
||||
LOG_DEBUG(Service_FS, "Only loading the first (bootable) NCCH within the NCSD file!");
|
||||
ncch_offset += 0x4000;
|
||||
file.Seek(ncch_offset, SEEK_SET);
|
||||
file.ReadBytes(&ncch_header, sizeof(NCCH_Header));
|
||||
}
|
||||
|
||||
// Verify we are loading the correct file type...
|
||||
if (Loader::MakeMagic('N', 'C', 'C', 'H') != ncch_header.magic)
|
||||
return Loader::ResultStatus::ErrorInvalidFormat;
|
||||
|
||||
has_header = true;
|
||||
return Loader::ResultStatus::Success;
|
||||
}
|
||||
|
||||
Loader::ResultStatus NCCHContainer::Load() {
|
||||
LOG_INFO(Service_FS, "Loading NCCH from file {}", filepath);
|
||||
if (is_loaded)
|
||||
return Loader::ResultStatus::Success;
|
||||
|
||||
|
@ -697,7 +726,7 @@ Loader::ResultStatus NCCHContainer::ReadOverrideRomFS(std::shared_ptr<RomFSReade
|
|||
}
|
||||
|
||||
Loader::ResultStatus NCCHContainer::ReadProgramId(u64_le& program_id) {
|
||||
Loader::ResultStatus result = Load();
|
||||
Loader::ResultStatus result = LoadHeader();
|
||||
if (result != Loader::ResultStatus::Success)
|
||||
return result;
|
||||
|
||||
|
|
|
@ -210,6 +210,12 @@ public:
|
|||
|
||||
Loader::ResultStatus OpenFile(const std::string& filepath, u32 ncch_offset = 0);
|
||||
|
||||
/**
|
||||
* Ensure NCCH header is loaded and ready for reading sections
|
||||
* @return ResultStatus result of function
|
||||
*/
|
||||
Loader::ResultStatus LoadHeader();
|
||||
|
||||
/**
|
||||
* Ensure ExeFS and exheader is loaded and ready for reading sections
|
||||
* @return ResultStatus result of function
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <fmt/format.h>
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/common_paths.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/errors.h"
|
||||
|
@ -33,6 +34,16 @@
|
|||
#include "core/loader/loader.h"
|
||||
#include "core/loader/smdh.h"
|
||||
|
||||
namespace {
|
||||
bool HasSupportedFileExtension(std::string path) {
|
||||
static const std::array<std::string, 7> extensions = {{".3ds", ".3dsx", ".elf", ".axf",
|
||||
".cci", ".cxi" ".app"
|
||||
}};
|
||||
const auto file_ext = FileUtil::GetExtensionFromFilename(path);
|
||||
return std::find(extensions.begin(), extensions.end(), file_ext) != extensions.end();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Service::AM {
|
||||
|
||||
constexpr u16 PLATFORM_CTR = 0x0004;
|
||||
|
@ -373,6 +384,36 @@ InstallStatus InstallCIA(const std::string& path,
|
|||
installFile.Close();
|
||||
|
||||
LOG_INFO(Service_AM, "Installed {} successfully.", path);
|
||||
|
||||
const FileUtil::DirectoryEntryCallable callback = [&callback](u64* num_entries_out,
|
||||
const std::string& directory,
|
||||
const std::string& virtual_name) -> bool {
|
||||
const std::string physical_name = directory + DIR_SEP + virtual_name;
|
||||
const bool is_dir = FileUtil::IsDirectory(physical_name);
|
||||
if (!is_dir && HasSupportedFileExtension(physical_name)) {
|
||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name);
|
||||
if (!loader)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool executable = false;
|
||||
auto res = loader->IsExecutable(executable);
|
||||
if (res == Loader::ResultStatus::ErrorEncrypted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return FileUtil::ForeachDirectoryEntry(nullptr, physical_name, callback);
|
||||
}
|
||||
|
||||
};
|
||||
if (!FileUtil::ForeachDirectoryEntry(nullptr, path, callback))
|
||||
{
|
||||
LOG_ERROR(Service_AM, "CIA {} contained encrypted files.", path);
|
||||
return InstallStatus::ErrorEncrypted;
|
||||
}
|
||||
return InstallStatus::Success;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue