summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/am/applets/general_backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/am/applets/general_backend.cpp')
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp
index 54c155dd8..e0def8dff 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/general_backend.cpp
@@ -17,6 +17,8 @@
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()) {
@@ -35,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;