From 03d7faf58390216729eb828b08be7e5f0ef82727 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Wed, 8 Aug 2018 23:41:12 +1000 Subject: [PATCH] GetProfileBase and GetProfileBaseAndData added --- src/core/hle/service/acc/acc.cpp | 77 +++++++++----------- src/core/hle/service/acc/profile_manager.cpp | 60 +++++++++++++++ src/core/hle/service/acc/profile_manager.h | 13 +++- 3 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 8efaf6171..92141f61c 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -27,19 +27,13 @@ struct UserData { }; static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); -struct ProfileBase { - UUID user_id; - u64 timestamp; - std::array username; -}; -static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); - // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? static UUID DEFAULT_USER_ID{1ull, 0ull}; class IProfile final : public ServiceFramework { public: - explicit IProfile(UUID user_id) : ServiceFramework("IProfile"), user_id(user_id) { + explicit IProfile(UUID user_id, ProfileManager& profile_manager) + : ServiceFramework("IProfile"), user_id(user_id), profile_manager(profile_manager) { static const FunctionInfo functions[] = { {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, @@ -51,40 +45,41 @@ public: private: void Get(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - profile_base.user_id = user_id; - if (Settings::values.username.size() > profile_base.username.size()) { + std::array data{}; + /*if (Settings::values.username.size() > profile_base.username.size()) { std::copy_n(Settings::values.username.begin(), profile_base.username.size(), profile_base.username.begin()); } else { std::copy(Settings::values.username.begin(), Settings::values.username.end(), profile_base.username.begin()); + }*/ + if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { + ctx.WriteBuffer(data); + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); + } else { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } - - IPC::ResponseBuilder rb{ctx, 16}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_base); } void GetBase(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - - // TODO(Subv): Retrieve this information from somewhere. + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - profile_base.user_id = user_id; - if (Settings::values.username.size() > profile_base.username.size()) { - std::copy_n(Settings::values.username.begin(), profile_base.username.size(), - profile_base.username.begin()); + if (profile_manager.GetProfileBase(user_id, profile_base)) { + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); } else { - std::copy(Settings::values.username.begin(), Settings::values.username.end(), - profile_base.username.begin()); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } - IPC::ResponseBuilder rb{ctx, 16}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_base); } + ProfileManager& profile_manager; UUID user_id; ///< The user id this profile refers to. }; @@ -139,29 +134,32 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { } void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): There is only one user for now. - const std::vector user_ids = {DEFAULT_USER_ID}; - ctx.WriteBuffer(user_ids); + LOG_INFO(Service_ACC, "called"); + ctx.WriteBuffer(profile_manager->GetAllUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): There is only one user for now. - const std::vector user_ids = {DEFAULT_USER_ID}; - ctx.WriteBuffer(user_ids); + LOG_INFO(Service_ACC, "called"); + ctx.WriteBuffer(profile_manager->GetOpenUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } +void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { + LOG_INFO(Service_ACC, "called"); + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_manager->GetLastOpennedUser()); +} + void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; UUID user_id = rp.PopRaw(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(user_id); + rb.PushIpcInterface(user_id, *profile_manager); LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); } @@ -178,13 +176,6 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo LOG_DEBUG(Service_ACC, "called"); } -void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(DEFAULT_USER_ID); -} - Module::Interface::Interface(std::shared_ptr module, const char* name) : ServiceFramework(name), module(std::move(module)) {} diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 8819c5703..925022018 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -43,10 +43,13 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array usernam prof_inf.username = username; prof_inf.data = std::array(); prof_inf.creation_time = 0x0; + prof_inf.is_open = false; return AddUser(prof_inf); } size_t ProfileManager::GetUserIndex(UUID uuid) { + if (!uuid) + return -1; for (unsigned i = 0; i < user_count; i++) if (profiles[i].user_uuid == uuid) return i; @@ -86,4 +89,61 @@ bool ProfileManager::UserExists(UUID uuid) { return (GetUserIndex(uuid) != -1); } +void ProfileManager::OpenUser(UUID uuid) { + auto idx = GetUserIndex(uuid); + if (idx == -1) + return; + profiles[idx].is_open = true; + last_openned_user = uuid; +} + +void ProfileManager::CloseUser(UUID uuid) { + auto idx = GetUserIndex(uuid); + if (idx == -1) + return; + profiles[idx].is_open = false; +} + +std::array ProfileManager::GetAllUsers() { + std::array output; + for (unsigned i = 0; i < user_count; i++) { + output[i] = profiles[i].user_uuid; + } + return output; +} + +std::array ProfileManager::GetOpenUsers() { + std::array output; + unsigned user_idx = 0; + for (unsigned i = 0; i < user_count; i++) { + if (profiles[i].is_open) { + output[i++] = profiles[i].user_uuid; + } + } + return output; +} + +const UUID& ProfileManager::GetLastOpennedUser() { + return last_openned_user; +} + +bool ProfileManager::GetProfileBaseAndData(size_t index, ProfileBase& profile, + std::array& data) { + if (GetProfileBase(index, profile)) { + std::memcpy(data.data(), profiles[index].data.data(), MAX_DATA); + return true; + } + return false; +} +bool ProfileManager::GetProfileBaseAndData(UUID uuid, ProfileBase& profile, + std::array& data) { + auto idx = GetUserIndex(uuid); + return GetProfileBaseAndData(idx, profile, data); +} + +bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, + std::array& data) { + return GetProfileBaseAndData(user.user_uuid, profile, data); +} + }; // namespace Service::Account diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 5aa73a030..cb6239cc1 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -54,7 +54,8 @@ struct ProfileInfo { UUID user_uuid; std::array username; u64 creation_time; - std::array data; + std::array data; // TODO(ognik): Work out what this is + bool is_open; }; struct ProfileBase { @@ -83,14 +84,24 @@ public: bool GetProfileBase(size_t index, ProfileBase& profile); bool GetProfileBase(UUID uuid, ProfileBase& profile); bool GetProfileBase(ProfileInfo user, ProfileBase& profile); + bool GetProfileBaseAndData(size_t index, ProfileBase& profile, std::array& data); + bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, std::array& data); + bool GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, + std::array& data); size_t GetUserCount(); bool UserExists(UUID uuid); + void OpenUser(UUID uuid); + void CloseUser(UUID uuid); + std::array GetOpenUsers(); + std::array GetAllUsers(); + const UUID& GetLastOpennedUser(); private: std::array profiles{}; size_t user_count = 0; size_t AddToProfiles(const ProfileInfo& profile); bool RemoveProfileAtIdx(size_t index); + UUID last_openned_user{0, 0}; }; using ProfileManagerPtr = std::unique_ptr;