diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/acc/acc.cpp | 34 | ||||
-rw-r--r-- | src/core/hle/service/acc/acc.h | 1 | ||||
-rw-r--r-- | src/core/hle/service/acc/acc_u0.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/acc/profile_manager.cpp | 25 | ||||
-rw-r--r-- | src/core/hle/service/acc/profile_manager.h | 3 | ||||
-rw-r--r-- | src/core/hle/service/sm/sm.cpp | 7 | ||||
-rw-r--r-- | src/core/hle/service/sm/sm_controller.cpp | 33 |
8 files changed, 73 insertions, 38 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index d57b42fdf..cc88d08f0 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -1185,8 +1185,10 @@ void KThread::RequestDummyThreadWait() { } void KThread::DummyThreadBeginWait() { - ASSERT(this->IsDummyThread()); - ASSERT(!kernel.IsPhantomModeForSingleCore()); + if (!this->IsDummyThread() || kernel.IsPhantomModeForSingleCore()) { + // Occurs in single core mode. + return; + } // Block until runnable is no longer false. dummy_thread_runnable.wait(false); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index bb838e285..85a3f0802 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -512,10 +512,11 @@ protected: class IManagerForApplication final : public ServiceFramework<IManagerForApplication> { public: - explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_) + explicit IManagerForApplication(Core::System& system_, + const std::shared_ptr<ProfileManager>& profile_manager_) : ServiceFramework{system_, "IManagerForApplication"}, ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)}, - user_id{user_id_} { + profile_manager{profile_manager_} { // clang-format off static const FunctionInfo functions[] = { {0, &IManagerForApplication::CheckAvailability, "CheckAvailability"}, @@ -545,7 +546,7 @@ private: IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.PushRaw<u64>(user_id.Hash()); + rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash()); } void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) { @@ -575,17 +576,20 @@ private: IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.PushRaw<u64>(user_id.Hash()); + rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash()); } void StoreOpenContext(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_DEBUG(Service_ACC, "called"); + + profile_manager->StoreOpenedUsers(); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{}; - Common::UUID user_id{}; + std::shared_ptr<ProfileManager> profile_manager; }; // 6.0.0+ @@ -790,7 +794,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo LOG_DEBUG(Service_ACC, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser()); + rb.PushIpcInterface<IManagerForApplication>(system, profile_manager); } void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) { @@ -849,22 +853,10 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) { rb.Push(ResultSuccess); } -void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - - // This is similar to GetBaasAccountManagerForApplication - // This command is used concurrently with ListOpenContextStoredUsers - // TODO: Find the differences between this and GetBaasAccountManagerForApplication - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser()); -} - void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_DEBUG(Service_ACC, "called"); - // TODO(ogniK): Handle open contexts - ctx.WriteBuffer(profile_manager->GetOpenUsers()); + ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index 1621e7c0a..9411b0b92 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -35,7 +35,6 @@ public: void InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx); void GetProfileEditor(Kernel::HLERequestContext& ctx); void ListQualifiedUsers(Kernel::HLERequestContext& ctx); - void LoadOpenContext(Kernel::HLERequestContext& ctx); void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx); void StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx); void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index 65023b8c2..54844bfe7 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp @@ -28,7 +28,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> {110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"}, {111, nullptr, "ClearSaveDataThumbnail"}, {120, nullptr, "CreateGuestLoginRequest"}, - {130, &ACC_U0::LoadOpenContext, "LoadOpenContext"}, // 5.0.0+ + {130, nullptr, "LoadOpenContext"}, // 5.0.0+ {131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+ {140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+ {141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+ diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index a58da4d5f..481e0d141 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -261,6 +261,31 @@ UUID ProfileManager::GetLastOpenedUser() const { return last_opened_user; } +/// Gets the list of stored opened users. +UserIDArray ProfileManager::GetStoredOpenedUsers() const { + UserIDArray output{}; + std::ranges::transform(stored_opened_profiles, output.begin(), [](const ProfileInfo& p) { + if (p.is_open) + return p.user_uuid; + return Common::InvalidUUID; + }); + std::stable_partition(output.begin(), output.end(), + [](const UUID& uuid) { return uuid.IsValid(); }); + return output; +} + +/// Captures the opened users, which can be queried across process launches with +/// ListOpenContextStoredUsers. +void ProfileManager::StoreOpenedUsers() { + size_t profile_index{}; + stored_opened_profiles = {}; + std::for_each(profiles.begin(), profiles.end(), [&](const auto& profile) { + if (profile.is_open) { + stored_opened_profiles[profile_index++] = profile; + } + }); +} + /// Return the users profile base and the unknown arbitary data. bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile, UserData& data) const { diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 135f7d0d5..993a5a57a 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -86,6 +86,8 @@ public: UserIDArray GetOpenUsers() const; UserIDArray GetAllUsers() const; Common::UUID GetLastOpenedUser() const; + UserIDArray GetStoredOpenedUsers() const; + void StoreOpenedUsers(); bool CanSystemRegisterUser() const; @@ -101,6 +103,7 @@ private: bool RemoveProfileAtIndex(std::size_t index); std::array<ProfileInfo, MAX_USERS> profiles{}; + std::array<ProfileInfo, MAX_USERS> stored_opened_profiles{}; std::size_t user_count{}; Common::UUID last_opened_user{}; }; diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index e2b8d8720..cb6c0e96f 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -149,9 +149,10 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& return port_result.Code(); } auto& port = port_result.Unwrap(); - SCOPE_EXIT({ port->GetClientPort().Close(); }); - - kernel.RegisterServerObject(&port->GetServerPort()); + SCOPE_EXIT({ + port->GetClientPort().Close(); + port->GetServerPort().Close(); + }); // Create a new session. Kernel::KClientSession* session{}; diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 273f79568..46a8439d8 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp @@ -28,23 +28,36 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service, "called"); + auto& process = *ctx.GetThread().GetOwnerProcess(); auto& parent_session = *ctx.Session()->GetParent(); - auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort(); auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager(); + auto& session_handler = session_manager->SessionHandler(); - // Create a session. - Kernel::KClientSession* session{}; - const Result result = parent_port.CreateSession(std::addressof(session), session_manager); - if (result.IsError()) { - LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - } + // FIXME: this is duplicated from the SVC, it should just call it instead + // once this is a proper process + + // Reserve a new session from the process resource limit. + Kernel::KScopedResourceReservation session_reservation(&process, + Kernel::LimitableResource::Sessions); + ASSERT(session_reservation.Succeeded()); + + // Create the session. + Kernel::KSession* session = Kernel::KSession::Create(system.Kernel()); + ASSERT(session != nullptr); + + // Initialize the session. + session->Initialize(nullptr, parent_session.GetName(), session_manager); + + // Commit the session reservation. + session_reservation.Commit(); + + // Register the session. + session_handler.ClientConnected(&session->GetServerSession()); // We succeeded. IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(ResultSuccess); - rb.PushMoveObjects(session); + rb.PushMoveObjects(session->GetClientSession()); } void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { |