summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-05-01 22:40:51 -0400
committerGravatar Zach Hilman2019-09-30 17:27:23 -0400
commitfe8c7e66e291b1fb3bef206e0d5809ad80441e9b (patch)
tree710fde640e7c6785cdad860e154a59054ffbcd05 /src
parentconfigure_service: Allow Qt to open external links (diff)
downloadyuzu-fe8c7e66e291b1fb3bef206e0d5809ad80441e9b.tar.gz
yuzu-fe8c7e66e291b1fb3bef206e0d5809ad80441e9b.tar.xz
yuzu-fe8c7e66e291b1fb3bef206e0d5809ad80441e9b.zip
am: Unstub PopLaunchParameter and add bcat connection for app-specific data
Previously we were simply returning the account-preselect structure all times but if passed with a different mode the game expects application-specific data. This also adds a hook for BCAT into this allowing us to send the launch parameter through bcat,
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/am.cpp66
-rw-r--r--src/core/hle/service/am/am.h2
2 files changed, 52 insertions, 16 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 797c9a06f..79f9a393e 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -31,6 +31,7 @@
31#include "core/hle/service/am/tcap.h" 31#include "core/hle/service/am/tcap.h"
32#include "core/hle/service/apm/controller.h" 32#include "core/hle/service/apm/controller.h"
33#include "core/hle/service/apm/interface.h" 33#include "core/hle/service/apm/interface.h"
34#include "core/hle/service/bcat/backend/backend.h"
34#include "core/hle/service/filesystem/filesystem.h" 35#include "core/hle/service/filesystem/filesystem.h"
35#include "core/hle/service/ns/ns.h" 36#include "core/hle/service/ns/ns.h"
36#include "core/hle/service/nvflinger/nvflinger.h" 37#include "core/hle/service/nvflinger/nvflinger.h"
@@ -46,15 +47,20 @@ constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2};
46constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3}; 47constexpr ResultCode ERR_NO_MESSAGES{ErrorModule::AM, 0x3};
47constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7}; 48constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7};
48 49
49constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA; 50enum class LaunchParameterKind : u32 {
51 ApplicationSpecific = 1,
52 AccountPreselectedUser = 2,
53};
54
55constexpr u32 LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC = 0xC79497CA;
50 56
51struct LaunchParameters { 57struct LaunchParameterAccountPreselectedUser {
52 u32_le magic; 58 u32_le magic;
53 u32_le is_account_selected; 59 u32_le is_account_selected;
54 u128 current_user; 60 u128 current_user;
55 INSERT_PADDING_BYTES(0x70); 61 INSERT_PADDING_BYTES(0x70);
56}; 62};
57static_assert(sizeof(LaunchParameters) == 0x88); 63static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88);
58 64
59IWindowController::IWindowController(Core::System& system_) 65IWindowController::IWindowController(Core::System& system_)
60 : ServiceFramework("IWindowController"), system{system_} { 66 : ServiceFramework("IWindowController"), system{system_} {
@@ -1128,26 +1134,54 @@ void IApplicationFunctions::EndBlockingHomeButton(Kernel::HLERequestContext& ctx
1128} 1134}
1129 1135
1130void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { 1136void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
1131 LOG_DEBUG(Service_AM, "called"); 1137 IPC::RequestParser rp{ctx};
1138 const auto kind = rp.PopEnum<LaunchParameterKind>();
1132 1139
1133 LaunchParameters params{}; 1140 LOG_DEBUG(Service_AM, "called, kind={:08X}", static_cast<u8>(kind));
1134 1141
1135 params.magic = POP_LAUNCH_PARAMETER_MAGIC; 1142 if (kind == LaunchParameterKind::ApplicationSpecific && !launch_popped_application_specific) {
1136 params.is_account_selected = 1; 1143 const auto backend = BCAT::CreateBackendFromSettings(&FileSystem::GetBCATDirectory);
1144 const auto build_id_full = Core::System::GetInstance().GetCurrentProcessBuildID();
1145 u64 build_id{};
1146 std::memcpy(&build_id, build_id_full.data(), sizeof(u64));
1137 1147
1138 Account::ProfileManager profile_manager{}; 1148 const auto data =
1139 const auto uuid = profile_manager.GetUser(Settings::values.current_user); 1149 backend->GetLaunchParameter({Core::CurrentProcess()->GetTitleID(), build_id});
1140 ASSERT(uuid);
1141 params.current_user = uuid->uuid;
1142 1150
1143 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 1151 if (data.has_value()) {
1152 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1153 rb.Push(RESULT_SUCCESS);
1154 rb.PushIpcInterface<AM::IStorage>(*data);
1155 launch_popped_application_specific = true;
1156 return;
1157 }
1158 } else if (kind == LaunchParameterKind::AccountPreselectedUser &&
1159 !launch_popped_account_preselect) {
1160 LaunchParameterAccountPreselectedUser params{};
1144 1161
1145 rb.Push(RESULT_SUCCESS); 1162 params.magic = LAUNCH_PARAMETER_ACCOUNT_PRESELECTED_USER_MAGIC;
1163 params.is_account_selected = 1;
1146 1164
1147 std::vector<u8> buffer(sizeof(LaunchParameters)); 1165 Account::ProfileManager profile_manager{};
1148 std::memcpy(buffer.data(), &params, buffer.size()); 1166 const auto uuid = profile_manager.GetUser(Settings::values.current_user);
1167 ASSERT(uuid);
1168 params.current_user = uuid->uuid;
1149 1169
1150 rb.PushIpcInterface<AM::IStorage>(buffer); 1170 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1171
1172 rb.Push(RESULT_SUCCESS);
1173
1174 std::vector<u8> buffer(sizeof(LaunchParameterAccountPreselectedUser));
1175 std::memcpy(buffer.data(), &params, buffer.size());
1176
1177 rb.PushIpcInterface<AM::IStorage>(buffer);
1178 launch_popped_account_preselect = true;
1179 return;
1180 }
1181
1182 LOG_ERROR(Service_AM, "Attempted to load launch parameter but none was found!");
1183 IPC::ResponseBuilder rb{ctx, 2};
1184 rb.Push(ERR_NO_DATA_IN_CHANNEL);
1151} 1185}
1152 1186
1153void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest( 1187void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index a3baeb673..9169eb2bd 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -255,6 +255,8 @@ private:
255 void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); 255 void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx);
256 void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); 256 void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
257 257
258 bool launch_popped_application_specific = false;
259 bool launch_popped_account_preselect = false;
258 Kernel::EventPair gpu_error_detected_event; 260 Kernel::EventPair gpu_error_detected_event;
259 Core::System& system; 261 Core::System& system;
260}; 262};