summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Marcec <dmarcecguzman@gmail.com>2019-06-27 16:44:42 +1000
committerDavid Marcec <dmarcecguzman@gmail.com>2019-06-27 16:44:42 +1000
commit0b03e8a98fc7685e5b44292327e1b31de27e9bcd (patch)
treeb19bdd1fb7c812c17af02a4c0268ada73a22f263 /src
parent5829ba1ccc18c083a4d2a6e42ad27ebe1c6fbac8 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/acc/acc.cpp80
-rw-r--r--src/core/hle/service/acc/acc.h24
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp4
-rw-r--r--src/core/hle/service/acc/errors.h12
4 files changed, 114 insertions, 6 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 0cd8158df..6aabe7409 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -15,13 +15,18 @@
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/kernel.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/errors.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"
namespace Service::Account {
@@ -217,10 +222,79 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon
rb.Push(profile_manager->CanSystemRegisterUser());
}
-void Module::Interface::InitializeApplicationInfoOld(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_ACC, "(STUBBED) called");
+void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ auto pid = rp.Pop<u64>();
+
+ LOG_DEBUG(Service_ACC, "called, process_id={}", pid);
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) {
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 350f123a0..f651773b7 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -4,6 +4,7 @@
#pragma once
+#include "core/hle/service/glue/manager.h"
#include "core/hle/service/service.h"
namespace Service::Account {
@@ -25,12 +26,33 @@ public:
void ListOpenUsers(Kernel::HLERequestContext& ctx);
void GetLastOpenedUser(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 IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx);
void TrySelectUserWithoutInteraction(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:
std::shared_ptr<Module> module;
std::shared_ptr<ProfileManager> profile_manager;
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
index 2f239e8c0..0ac19f4ff 100644
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ b/src/core/hle/service/acc/acc_u0.cpp
@@ -22,7 +22,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, nullptr, "ListOpenContextStoredUsers"},
{99, nullptr, "DebugActivateOpenContextRetention"},
- {100, &ACC_U0::InitializeApplicationInfoOld, "InitializeApplicationInfoOld"},
+ {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
{102, nullptr, "AuthenticateApplicationAsync"},
{103, nullptr, "CheckNetworkServiceAvailabilityAsync"},
@@ -31,7 +31,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{120, nullptr, "CreateGuestLoginRequest"},
{130, nullptr, "LoadOpenContext"},
{131, nullptr, "ListOpenContextStoredUsers"},
- {140, nullptr, "InitializeApplicationInfo"},
+ {140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"},
{141, nullptr, "ListQualifiedUsers"},
{150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"},
};
diff --git a/src/core/hle/service/acc/errors.h b/src/core/hle/service/acc/errors.h
new file mode 100644
index 000000000..86876dfd6
--- /dev/null
+++ b/src/core/hle/service/acc/errors.h
@@ -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