Implemented InitializeApplicationInfo & InitializeApplicationInfoRestricted

InitializeApplicationInfoRestricted will need further implementation as it's checking for other user requirements about the game. As we're emulating, we're assuming the user owns the game so we skip these checks currently, implementation will need to be added further on
This commit is contained in:
David Marcec 2019-06-27 16:44:42 +10:00
parent 5829ba1ccc
commit 0b03e8a98f
4 changed files with 114 additions and 6 deletions

View file

@ -15,13 +15,18 @@
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc.h"
#include "core/hle/service/acc/acc_aa.h" #include "core/hle/service/acc/acc_aa.h"
#include "core/hle/service/acc/acc_su.h" #include "core/hle/service/acc/acc_su.h"
#include "core/hle/service/acc/acc_u0.h" #include "core/hle/service/acc/acc_u0.h"
#include "core/hle/service/acc/acc_u1.h" #include "core/hle/service/acc/acc_u1.h"
#include "core/hle/service/acc/errors.h"
#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/glue/arp.h"
#include "core/hle/service/glue/manager.h"
#include "core/hle/service/sm/sm.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
namespace Service::Account { namespace Service::Account {
@ -217,10 +222,79 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
rb.Push(profile_manager->CanSystemRegisterUser()); rb.Push(profile_manager->CanSystemRegisterUser());
} }
void Module::Interface::InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx) { void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::RequestParser rp{ctx};
auto pid = rp.Pop<u64>();
LOG_DEBUG(Service_ACC, "called, process_id={}", pid);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(InitializeApplicationInfoBase(pid));
}
void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto pid = rp.Pop<u64>();
LOG_WARNING(Service_ACC, "(Partial implementation) called, process_id={}", pid);
const auto res = InitializeApplicationInfoBase(pid);
// TODO(ogniK): We require checking if the user actually owns the title and what not. As of
// currently, we assume the user owns the title.
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res);
}
ResultCode Module::Interface::InitializeApplicationInfoBase(u64 process_id) {
if (application_info) {
return ERR_ACCOUNTINFO_ALREADY_INITIALIZED;
}
Service::SM::ServiceManager& sm = system.ServiceManager();
std::shared_ptr<Service::Glue::ARP_R> arp_r = sm.GetService<Service::Glue::ARP_R>("arp:r");
if (arp_r == nullptr) {
LOG_ERROR(Service_ACC, "Failed to get arp:r service");
application_info.application_type = ApplicationType::Unknown;
return ResultCode(ERR_ACCOUNTINFO_BAD_APPLICATION);
}
const auto& list = system.Kernel().GetProcessList();
const auto iter = std::find_if(list.begin(), list.end(), [&process_id](const auto& process) {
return process->GetProcessID() == process_id;
});
if (iter == list.end()) {
// Failed to find process ID
application_info.application_type = ApplicationType::Unknown;
return ResultCode(ERR_ACCOUNTINFO_BAD_APPLICATION);
}
const auto launch_property = system.GetARPManager().GetLaunchProperty((*iter)->GetTitleID());
if (launch_property.Failed()) {
return ResultCode(ERR_ACCOUNTINFO_BAD_APPLICATION);
}
switch (launch_property->base_game_storage_id) {
case FileSys::StorageId::GameCard:
application_info.application_type = ApplicationType::GameCard;
break;
case FileSys::StorageId::Host:
case FileSys::StorageId::NandUser:
case FileSys::StorageId::SdCard:
application_info.application_type = ApplicationType::Digital;
break;
default:
return ResultCode(ERR_ACCOUNTINFO_BAD_APPLICATION);
}
LOG_WARNING(Service_ACC, "ApplicationInfo init required");
// TODO(ogniK): Actual initalization here
return RESULT_SUCCESS;
} }
void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) { void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) {

View file

@ -4,6 +4,7 @@
#pragma once #pragma once
#include "core/hle/service/glue/manager.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Service::Account { namespace Service::Account {
@ -25,12 +26,33 @@ public:
void ListOpenUsers(Kernel::HLERequestContext& ctx); void ListOpenUsers(Kernel::HLERequestContext& ctx);
void GetLastOpenedUser(Kernel::HLERequestContext& ctx); void GetLastOpenedUser(Kernel::HLERequestContext& ctx);
void GetProfile(Kernel::HLERequestContext& ctx); void GetProfile(Kernel::HLERequestContext& ctx);
void InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx); void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
void InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx);
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx); void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx); void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx);
void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx); void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx); void IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx);
private:
ResultCode InitializeApplicationInfoBase(u64 process_id);
enum class ApplicationType : u32_le {
GameCard = 0,
Digital = 1,
Unknown = 3,
};
struct ApplicationInfo {
Service::Glue::ApplicationLaunchProperty launch_property;
ApplicationType application_type;
constexpr explicit operator bool() const {
return launch_property.title_id != 0x0;
}
};
ApplicationInfo application_info{};
protected: protected:
std::shared_ptr<Module> module; std::shared_ptr<Module> module;
std::shared_ptr<ProfileManager> profile_manager; std::shared_ptr<ProfileManager> profile_manager;

View file

@ -22,7 +22,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, nullptr, "ListOpenContextStoredUsers"}, {60, nullptr, "ListOpenContextStoredUsers"},
{99, nullptr, "DebugActivateOpenContextRetention"}, {99, nullptr, "DebugActivateOpenContextRetention"},
{100, &ACC_U0::InitializeApplicationInfoOld, "InitializeApplicationInfoOld"}, {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"}, {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
{102, nullptr, "AuthenticateApplicationAsync"}, {102, nullptr, "AuthenticateApplicationAsync"},
{103, nullptr, "CheckNetworkServiceAvailabilityAsync"}, {103, nullptr, "CheckNetworkServiceAvailabilityAsync"},
@ -31,7 +31,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{120, nullptr, "CreateGuestLoginRequest"}, {120, nullptr, "CreateGuestLoginRequest"},
{130, nullptr, "LoadOpenContext"}, {130, nullptr, "LoadOpenContext"},
{131, nullptr, "ListOpenContextStoredUsers"}, {131, nullptr, "ListOpenContextStoredUsers"},
{140, nullptr, "InitializeApplicationInfo"}, {140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"},
{141, nullptr, "ListQualifiedUsers"}, {141, nullptr, "ListQualifiedUsers"},
{150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"}, {150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"},
}; };

View file

@ -0,0 +1,12 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/result.h"
namespace Service::Account {
constexpr ResultCode ERR_ACCOUNTINFO_BAD_APPLICATION{ErrorModule::Account, 22};
constexpr ResultCode ERR_ACCOUNTINFO_ALREADY_INITIALIZED{ErrorModule::Account, 41};
} // namespace Service::Account