Compare commits

..

16 Commits

Author SHA1 Message Date
Jarek Syrylak
74f966404d Correct endianness of BKPT 2018-09-20 22:03:57 +01:00
bunnei
8fe9572271 Merge pull request #1358 from DarkLordZach/temp-storage
savedata_factory: Add TemporaryStorage SaveDataType
2018-09-20 10:13:38 -04:00
bunnei
0931a711de Merge pull request #1363 from lioncash/control
control_metadata: Move language name array definition to the cpp file
2018-09-20 10:13:23 -04:00
bunnei
b02a1e38fa Merge pull request #1361 from lioncash/nax
xts_archive/nax: Minor interface changes
2018-09-20 10:13:10 -04:00
bunnei
e57aa62b11 Merge pull request #1366 from ogniK5377/splat-fix
Implemented NTC & IEnsureNetworkClockAvailabilityService
2018-09-20 10:12:35 -04:00
David Marcec
583137709f Removed unneeded event clear 2018-09-20 15:16:08 +10:00
David Marcec
335e9d18ae Implemented NTC & IEnsureNetworkClockAvailabilityService
Needed because of the recent nim fixes
2018-09-20 15:14:07 +10:00
Lioncash
3146502a12 control_metadata: Remove unnecessary else within GetLanguageEntry()
There's no need to indent the code here, given the if case contains a
return statement at the end of it.
2018-09-19 19:02:06 -04:00
Lioncash
05d49962b6 control_metadata: Move language name array definition to the cpp file
This was used in two different translation units
(deconstructed_rom_directory and patch_manager). This means we'd be
pointlessly duplicating the whole array twice due to it being defined
within the header.
2018-09-19 18:57:26 -04:00
Lioncash
2e5f0e5024 xts_archive: Remove unused variables from CalculateHMAC256()
These variables aren't used, which still has an impact, as std::vector
cannot be optimized away by the compiler (it's constructor and
destructor are both non-trivial), so this was just wasting memory.
2018-09-19 14:23:13 -04:00
Lioncash
2752183883 xts_archive: Make AsNCA() return a std::unique_ptr instead of a std::shared_ptr
std::shared_ptr isn't strictly necessary here and is only ever used in
contexts where the object doesn't depend on being shared. This also
makes the interface more flexible, as it's possible to create a
std::shared_ptr from a std::unique_ptr (std::shared_ptr has a
constructor that accepts a std::unique_ptr), but not the other way
around.
2018-09-19 14:22:37 -04:00
Lioncash
45195a51a7 nax: Avoid re-parsing NAX data with GetFileType()
An instance of the NAX apploader already has an existing NAX instance in
memory. Calling directly into IdentifyType() directly would re-parse the
whole file again into yet another NAX instance, only to toss it away
again.

This gets rid of unnecessary/redundant file parsing and allocations.
2018-09-19 14:22:37 -04:00
Lioncash
c8c4105659 nax: Avoid unnecessary calls to AsNCA() in IdentifyType()
AsNCA() allocates an NCA instance every time it's called. In the current
manner it's used, it's quite inefficient as it's making a redundant
allocation.

We can just amend the order of the conditionals to make it easier to
just call it once.
2018-09-19 14:22:37 -04:00
Lioncash
f272261c21 xts_archive: Ensure NAX's type member is always initialized
Ensures that the member always has a deterministic value.
2018-09-19 14:22:37 -04:00
Lioncash
92a98a8b19 xts_archive: Amend initializer order of NAX's constructor
Orders the initializer list in the same order the members would be
initialized. Avoids compiler warnings.
2018-09-19 14:22:30 -04:00
Zach Hilman
dfaea55be5 savedata_factory: Add TemporaryStorage SaveDataType
Seems to be used by NSO NES Emulator
2018-09-19 09:06:22 -04:00
11 changed files with 151 additions and 54 deletions

View File

@@ -12,7 +12,6 @@
#include "core/core.h"
#include "core/core_cpu.h"
#include "core/core_timing.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc.h"
#include "core/memory.h"
@@ -80,17 +79,6 @@ public:
case Dynarmic::A64::Exception::SendEventLocal:
case Dynarmic::A64::Exception::Yield:
return;
case Dynarmic::A64::Exception::Breakpoint:
if (GDBStub::IsServerEnabled()) {
parent.jit->HaltExecution();
parent.SetPC(pc);
Kernel::Thread* thread = Kernel::GetCurrentThread();
parent.SaveContext(thread->context);
GDBStub::Break();
GDBStub::SendTrap(thread, 5);
return;
}
[[fallthrough]];
default:
ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:X})",
static_cast<std::size_t>(exception), pc);

View File

@@ -8,6 +8,14 @@
namespace FileSys {
const std::array<const char*, 15> LANGUAGE_NAMES = {
"AmericanEnglish", "BritishEnglish", "Japanese",
"French", "German", "LatinAmericanSpanish",
"Spanish", "Italian", "Dutch",
"CanadianFrench", "Portugese", "Russian",
"Korean", "Taiwanese", "Chinese",
};
std::string LanguageEntry::GetApplicationName() const {
return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), 0x200);
}
@@ -23,15 +31,15 @@ NACP::NACP(VirtualFile file) : raw(std::make_unique<RawNACP>()) {
const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
if (language != Language::Default) {
return raw->language_entries.at(static_cast<u8>(language));
} else {
for (const auto& language_entry : raw->language_entries) {
if (!language_entry.GetApplicationName().empty())
return language_entry;
}
// Fallback to English
return GetLanguageEntry(Language::AmericanEnglish);
}
for (const auto& language_entry : raw->language_entries) {
if (!language_entry.GetApplicationName().empty())
return language_entry;
}
// Fallback to English
return GetLanguageEntry(Language::AmericanEnglish);
}
std::string NACP::GetApplicationName(Language language) const {

View File

@@ -66,12 +66,7 @@ enum class Language : u8 {
Default = 255,
};
static constexpr std::array<const char*, 15> LANGUAGE_NAMES = {
"AmericanEnglish", "BritishEnglish", "Japanese",
"French", "German", "LatinAmericanSpanish",
"Spanish", "Italian", "Dutch",
"CanadianFrench", "Portugese", "Russian",
"Korean", "Taiwanese", "Chinese"};
extern const std::array<const char*, 15> LANGUAGE_NAMES;
// A class representing the format used by NX metadata files, typically named Control.nacp.
// These store application name, dev name, title id, and other miscellaneous data.

View File

@@ -85,10 +85,10 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
switch (space) {
case SaveDataSpaceId::NandSystem:
out = "/system/save/";
out = "/system/";
break;
case SaveDataSpaceId::NandUser:
out = "/user/save/";
out = "/user/";
break;
default:
ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space));
@@ -96,9 +96,12 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
switch (type) {
case SaveDataType::SystemSaveData:
return fmt::format("{}{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);
return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]);
case SaveDataType::SaveData:
return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0],
return fmt::format("{}save/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0],
title_id);
case SaveDataType::TemporaryStorage:
return fmt::format("{}temp/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0],
title_id);
default:
ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type));

View File

@@ -30,9 +30,6 @@ static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t
mbedtls_md_context_t context;
mbedtls_md_init(&context);
const auto key_f = reinterpret_cast<const u8*>(key);
const std::vector<u8> key_v(key_f, key_f + key_length);
if (mbedtls_md_setup(&context, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1) ||
mbedtls_md_hmac_starts(&context, reinterpret_cast<const u8*>(key), key_length) ||
mbedtls_md_hmac_update(&context, reinterpret_cast<const u8*>(data), data_length) ||
@@ -45,7 +42,7 @@ static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t
return true;
}
NAX::NAX(VirtualFile file_) : file(std::move(file_)), header(std::make_unique<NAXHeader>()) {
NAX::NAX(VirtualFile file_) : header(std::make_unique<NAXHeader>()), file(std::move(file_)) {
std::string path = FileUtil::SanitizePath(file->GetFullPath());
static const std::regex nax_path_regex("/registered/(000000[0-9A-F]{2})/([0-9A-F]{32})\\.nca",
std::regex_constants::ECMAScript |
@@ -65,7 +62,7 @@ NAX::NAX(VirtualFile file_) : file(std::move(file_)), header(std::make_unique<NA
}
NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id)
: file(std::move(file_)), header(std::make_unique<NAXHeader>()) {
: header(std::make_unique<NAXHeader>()), file(std::move(file_)) {
Core::Crypto::SHA256Hash hash{};
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0],
@@ -138,9 +135,9 @@ VirtualFile NAX::GetDecrypted() const {
return dec_file;
}
std::shared_ptr<NCA> NAX::AsNCA() const {
std::unique_ptr<NCA> NAX::AsNCA() const {
if (type == NAXContentType::NCA)
return std::make_shared<NCA>(GetDecrypted());
return std::make_unique<NCA>(GetDecrypted());
return nullptr;
}

View File

@@ -38,7 +38,7 @@ public:
VirtualFile GetDecrypted() const;
std::shared_ptr<NCA> AsNCA() const;
std::unique_ptr<NCA> AsNCA() const;
NAXContentType GetContentType() const;
@@ -60,7 +60,7 @@ private:
VirtualFile file;
Loader::ResultStatus status;
NAXContentType type;
NAXContentType type{};
VirtualFile dec_file;

View File

@@ -995,7 +995,7 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
breakpoint.addr = addr;
breakpoint.len = len;
Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}};
static constexpr std::array<u8, 4> btrap{{0x00, 0x7d, 0x20, 0xd4}};
Memory::WriteBlock(addr, btrap.data(), btrap.size());
Core::System::GetInstance().InvalidateCpuInstructionCaches();
p.insert({addr, breakpoint});

View File

@@ -2,6 +2,10 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <chrono>
#include <ctime>
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/nim/nim.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
@@ -100,19 +104,111 @@ public:
}
};
class IEnsureNetworkClockAvailabilityService final
: public ServiceFramework<IEnsureNetworkClockAvailabilityService> {
public:
IEnsureNetworkClockAvailabilityService()
: ServiceFramework("IEnsureNetworkClockAvailabilityService") {
static const FunctionInfo functions[] = {
{0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"},
{1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent,
"GetFinishNotificationEvent"},
{2, &IEnsureNetworkClockAvailabilityService::GetResult, "GetResult"},
{3, &IEnsureNetworkClockAvailabilityService::Cancel, "Cancel"},
{4, &IEnsureNetworkClockAvailabilityService::IsProcessing, "IsProcessing"},
{5, &IEnsureNetworkClockAvailabilityService::GetServerTime, "GetServerTime"},
};
RegisterHandlers(functions);
auto& kernel = Core::System::GetInstance().Kernel();
finished_event =
Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
"IEnsureNetworkClockAvailabilityService:FinishEvent");
}
private:
Kernel::SharedPtr<Kernel::Event> finished_event;
void StartTask(Kernel::HLERequestContext& ctx) {
// No need to connect to the internet, just finish the task straight away.
finished_event->Signal();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_NIM, "called");
}
void GetFinishNotificationEvent(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(finished_event);
LOG_DEBUG(Service_NIM, "called");
}
void GetResult(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_NIM, "called");
}
void Cancel(Kernel::HLERequestContext& ctx) {
finished_event->Clear();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_NIM, "called");
}
void IsProcessing(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.PushRaw<u32>(0); // We instantly process the request
LOG_DEBUG(Service_NIM, "called");
}
void GetServerTime(Kernel::HLERequestContext& ctx) {
const s64 server_time{std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch())
.count()};
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.PushRaw<s64>(server_time);
LOG_DEBUG(Service_NIM, "called");
}
};
class NTC final : public ServiceFramework<NTC> {
public:
explicit NTC() : ServiceFramework{"ntc"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "OpenEnsureNetworkClockAvailabilityService"},
{100, nullptr, "SuspendAutonomicTimeCorrection"},
{101, nullptr, "ResumeAutonomicTimeCorrection"},
{0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"},
{100, &NTC::SuspendAutonomicTimeCorrection, "SuspendAutonomicTimeCorrection"},
{101, &NTC::ResumeAutonomicTimeCorrection, "ResumeAutonomicTimeCorrection"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void OpenEnsureNetworkClockAvailabilityService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>();
LOG_DEBUG(Service_NIM, "called");
}
// TODO(ogniK): Do we need these?
void SuspendAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void ResumeAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
};
void InstallInterfaces(SM::ServiceManager& sm) {

View File

@@ -11,6 +11,20 @@
#include "core/loader/nca.h"
namespace Loader {
namespace {
FileType IdentifyTypeImpl(const FileSys::NAX& nax) {
if (nax.GetStatus() != ResultStatus::Success) {
return FileType::Error;
}
const auto nca = nax.AsNCA();
if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) {
return FileType::Error;
}
return FileType::NAX;
}
} // Anonymous namespace
AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file)
: AppLoader(file), nax(std::make_unique<FileSys::NAX>(file)),
@@ -19,14 +33,12 @@ AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file)
AppLoader_NAX::~AppLoader_NAX() = default;
FileType AppLoader_NAX::IdentifyType(const FileSys::VirtualFile& file) {
FileSys::NAX nax(file);
const FileSys::NAX nax(file);
return IdentifyTypeImpl(nax);
}
if (nax.GetStatus() == ResultStatus::Success && nax.AsNCA() != nullptr &&
nax.AsNCA()->GetStatus() == ResultStatus::Success) {
return FileType::NAX;
}
return FileType::Error;
FileType AppLoader_NAX::GetFileType() {
return IdentifyTypeImpl(*nax);
}
ResultStatus AppLoader_NAX::Load(Kernel::SharedPtr<Kernel::Process>& process) {

View File

@@ -31,9 +31,7 @@ public:
*/
static FileType IdentifyType(const FileSys::VirtualFile& file);
FileType GetFileType() override {
return IdentifyType(file);
}
FileType GetFileType() override;
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;