diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/am/applets/general_backend.cpp | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index 76fc8906d..e0def8dff 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp @@ -13,9 +13,12 @@ #include "core/hle/result.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/general_backend.h" +#include "core/reporter.h" namespace Service::AM::Applets { +constexpr ResultCode ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; + static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet(); for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) { @@ -34,6 +37,120 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) } } +Auth::Auth(Core::Frontend::ParentalControlsApplet& frontend) : frontend(frontend) {} + +Auth::~Auth() = default; + +void Auth::Initialize() { + Applet::Initialize(); + complete = false; + + const auto storage = broker.PopNormalDataToApplet(); + ASSERT(storage != nullptr); + const auto data = storage->GetData(); + ASSERT(data.size() >= 0xC); + + struct Arg { + INSERT_PADDING_BYTES(4); + AuthAppletType type; + u8 arg0; + u8 arg1; + u8 arg2; + INSERT_PADDING_BYTES(1); + }; + static_assert(sizeof(Arg) == 0xC, "Arg (AuthApplet) has incorrect size."); + + Arg arg{}; + std::memcpy(&arg, data.data(), sizeof(Arg)); + + type = arg.type; + arg0 = arg.arg0; + arg1 = arg.arg1; + arg2 = arg.arg2; +} + +bool Auth::TransactionComplete() const { + return complete; +} + +ResultCode Auth::GetStatus() const { + return successful ? RESULT_SUCCESS : ERROR_INVALID_PIN; +} + +void Auth::ExecuteInteractive() { + UNREACHABLE_MSG("Unexpected interactive applet data."); +} + +void Auth::Execute() { + if (complete) { + return; + } + + const auto unimplemented_log = [this] { + UNIMPLEMENTED_MSG("Unimplemented Auth applet type for type={:08X}, arg0={:02X}, " + "arg1={:02X}, arg2={:02X}", + static_cast<u32>(type), arg0, arg1, arg2); + }; + + switch (type) { + case AuthAppletType::ShowParentalAuthentication: { + const auto callback = [this](bool successful) { AuthFinished(successful); }; + + if (arg0 == 1 && arg1 == 0 && arg2 == 1) { + // ShowAuthenticatorForConfiguration + frontend.VerifyPINForSettings(callback); + } else if (arg1 == 0 && arg2 == 0) { + // ShowParentalAuthentication(bool) + frontend.VerifyPIN(callback, static_cast<bool>(arg0)); + } else { + unimplemented_log(); + } + break; + } + case AuthAppletType::RegisterParentalPasscode: { + const auto callback = [this] { AuthFinished(true); }; + + if (arg0 == 0 && arg1 == 0 && arg2 == 0) { + // RegisterParentalPasscode + frontend.RegisterPIN(callback); + } else { + unimplemented_log(); + } + break; + } + case AuthAppletType::ChangeParentalPasscode: { + const auto callback = [this] { AuthFinished(true); }; + + if (arg0 == 0 && arg1 == 0 && arg2 == 0) { + // ChangeParentalPasscode + frontend.ChangePIN(callback); + } else { + unimplemented_log(); + } + break; + } + default: + unimplemented_log(); + } +} + +void Auth::AuthFinished(bool successful) { + this->successful = successful; + + struct Return { + ResultCode result_code; + }; + static_assert(sizeof(Return) == 0x4, "Return (AuthApplet) has incorrect size."); + + Return return_{GetStatus()}; + + std::vector<u8> out(sizeof(Return)); + std::memcpy(out.data(), &return_, sizeof(Return)); + + broker.PushNormalDataFromApplet(IStorage{out}); + broker.SignalStateChanged(); +} + PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {} PhotoViewer::~PhotoViewer() = default; @@ -83,13 +200,20 @@ void PhotoViewer::ViewFinished() { broker.SignalStateChanged(); } -StubApplet::StubApplet() = default; +StubApplet::StubApplet(AppletId id) : id(id) {} StubApplet::~StubApplet() = default; void StubApplet::Initialize() { LOG_WARNING(Service_AM, "called (STUBBED)"); Applet::Initialize(); + + const auto data = broker.PeekDataToAppletForDebug(); + Core::System::GetInstance().GetReporter().SaveUnimplementedAppletReport( + static_cast<u32>(id), common_args.arguments_version, common_args.library_version, + common_args.theme_color, common_args.play_startup_sound, common_args.system_tick, + data.normal, data.interactive); + LogCurrentStorage(broker, "Initialize"); } |