summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/acc/acc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/acc/acc.cpp')
-rw-r--r--src/core/hle/service/acc/acc.cpp89
1 files changed, 56 insertions, 33 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index ba7d7acbd..025714e5a 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -10,31 +10,23 @@
#include "common/logging/log.h"
#include "common/string_util.h"
#include "common/swap.h"
+#include "core/constants.h"
#include "core/core_timing.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/process.h"
#include "core/hle/service/acc/acc.h"
#include "core/hle/service/acc/acc_aa.h"
#include "core/hle/service/acc/acc_su.h"
#include "core/hle/service/acc/acc_u0.h"
#include "core/hle/service/acc/acc_u1.h"
#include "core/hle/service/acc/profile_manager.h"
+#include "core/loader/loader.h"
namespace Service::Account {
-// Smallest JPEG https://github.com/mathiasbynens/small/blob/master/jpeg.jpg
-// used as a backup should the one on disk not exist
-constexpr u32 backup_jpeg_size = 107;
-constexpr std::array<u8, backup_jpeg_size> backup_jpeg{{
- 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
- 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x06, 0x06, 0x05,
- 0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, 0x0c, 0x0f, 0x0c, 0x0a, 0x0b, 0x0e,
- 0x0b, 0x09, 0x09, 0x0d, 0x11, 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x10, 0x0a, 0x0c, 0x12, 0x13,
- 0x12, 0x10, 0x13, 0x0f, 0x10, 0x10, 0x10, 0xff, 0xc9, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01,
- 0x01, 0x01, 0x11, 0x00, 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08,
- 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9,
-}};
-
-static std::string GetImagePath(UUID uuid) {
+static std::string GetImagePath(Common::UUID uuid) {
return FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
"/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg";
}
@@ -46,7 +38,7 @@ static constexpr u32 SanitizeJPEGSize(std::size_t size) {
class IProfile final : public ServiceFramework<IProfile> {
public:
- explicit IProfile(UUID user_id, ProfileManager& profile_manager)
+ explicit IProfile(Common::UUID user_id, ProfileManager& profile_manager)
: ServiceFramework("IProfile"), profile_manager(profile_manager), user_id(user_id) {
static const FunctionInfo functions[] = {
{0, &IProfile::Get, "Get"},
@@ -101,8 +93,8 @@ private:
if (!image.IsOpen()) {
LOG_WARNING(Service_ACC,
"Failed to load user provided image! Falling back to built-in backup...");
- ctx.WriteBuffer(backup_jpeg);
- rb.Push<u32>(backup_jpeg_size);
+ ctx.WriteBuffer(Core::Constants::ACCOUNT_BACKUP_JPEG);
+ rb.Push<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size());
return;
}
@@ -124,14 +116,14 @@ private:
if (!image.IsOpen()) {
LOG_WARNING(Service_ACC,
"Failed to load user provided image! Falling back to built-in backup...");
- rb.Push<u32>(backup_jpeg_size);
+ rb.Push<u32>(Core::Constants::ACCOUNT_BACKUP_JPEG.size());
} else {
rb.Push<u32>(SanitizeJPEGSize(image.GetSize()));
}
}
const ProfileManager& profile_manager;
- UUID user_id; ///< The user id this profile refers to.
+ Common::UUID user_id; ///< The user id this profile refers to.
};
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
@@ -179,7 +171,7 @@ void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) {
void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- UUID user_id = rp.PopRaw<UUID>();
+ Common::UUID user_id = rp.PopRaw<Common::UUID>();
LOG_INFO(Service_ACC, "called user_id={}", user_id.Format());
IPC::ResponseBuilder rb{ctx, 3};
@@ -205,12 +197,12 @@ void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) {
LOG_INFO(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
- rb.PushRaw<UUID>(profile_manager->GetLastOpenedUser());
+ rb.PushRaw<Common::UUID>(profile_manager->GetLastOpenedUser());
}
void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- UUID user_id = rp.PopRaw<UUID>();
+ Common::UUID user_id = rp.PopRaw<Common::UUID>();
LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -225,7 +217,7 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
rb.Push(profile_manager->CanSystemRegisterUser());
}
-void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
+void Module::Interface::InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -238,6 +230,31 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
rb.PushIpcInterface<IManagerForApplication>();
}
+void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_ACC, "called");
+ FileSys::NACP nacp;
+ const auto res = system.GetAppLoader().ReadControlData(nacp);
+
+ bool is_locked = false;
+
+ if (res != Loader::ResultStatus::Success) {
+ FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
+ auto nacp_unique = pm.GetControlMetadata().first;
+
+ if (nacp_unique != nullptr) {
+ is_locked = nacp_unique->GetUserAccountSwitchLock();
+ } else {
+ LOG_ERROR(Service_ACC, "nacp_unique is null!");
+ }
+ } else {
+ is_locked = nacp.GetUserAccountSwitchLock();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(is_locked);
+}
+
void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_ACC, "called");
// A u8 is passed into this function which we can safely ignore. It's to determine if we have
@@ -245,15 +262,15 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
IPC::ResponseBuilder rb{ctx, 6};
if (profile_manager->GetUserCount() != 1) {
rb.Push(RESULT_SUCCESS);
- rb.PushRaw<u128>(INVALID_UUID);
+ rb.PushRaw<u128>(Common::INVALID_UUID);
return;
}
const auto user_list = profile_manager->GetAllUsers();
if (std::all_of(user_list.begin(), user_list.end(),
- [](const auto& user) { return user.uuid == INVALID_UUID; })) {
+ [](const auto& user) { return user.uuid == Common::INVALID_UUID; })) {
rb.Push(ResultCode(-1)); // TODO(ogniK): Find the correct error code
- rb.PushRaw<u128>(INVALID_UUID);
+ rb.PushRaw<u128>(Common::INVALID_UUID);
return;
}
@@ -263,19 +280,25 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
}
Module::Interface::Interface(std::shared_ptr<Module> module,
- std::shared_ptr<ProfileManager> profile_manager, const char* name)
+ std::shared_ptr<ProfileManager> profile_manager, Core::System& system,
+ const char* name)
: ServiceFramework(name), module(std::move(module)),
- profile_manager(std::move(profile_manager)) {}
+ profile_manager(std::move(profile_manager)), system(system) {}
Module::Interface::~Interface() = default;
-void InstallInterfaces(SM::ServiceManager& service_manager) {
+void InstallInterfaces(Core::System& system) {
auto module = std::make_shared<Module>();
auto profile_manager = std::make_shared<ProfileManager>();
- std::make_shared<ACC_AA>(module, profile_manager)->InstallAsService(service_manager);
- std::make_shared<ACC_SU>(module, profile_manager)->InstallAsService(service_manager);
- std::make_shared<ACC_U0>(module, profile_manager)->InstallAsService(service_manager);
- std::make_shared<ACC_U1>(module, profile_manager)->InstallAsService(service_manager);
+
+ std::make_shared<ACC_AA>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<ACC_SU>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<ACC_U0>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
+ std::make_shared<ACC_U1>(module, profile_manager, system)
+ ->InstallAsService(system.ServiceManager());
}
} // namespace Service::Account