Browse Source
Merge pull request #2607 from DarkLordZach/arp-1
Merge pull request #2607 from DarkLordZach/arp-1
glue: Implement arp:w and arp:r servicesnce_cpp
committed by
GitHub
19 changed files with 730 additions and 97 deletions
-
11src/core/CMakeLists.txt
-
66src/core/core.cpp
-
8src/core/core.h
-
10src/core/file_sys/patch_manager.cpp
-
9src/core/file_sys/patch_manager.h
-
14src/core/file_sys/registered_cache.cpp
-
3src/core/file_sys/registered_cache.h
-
75src/core/hle/service/arp/arp.cpp
-
16src/core/hle/service/arp/arp.h
-
297src/core/hle/service/glue/arp.cpp
-
43src/core/hle/service/glue/arp.h
-
50src/core/hle/service/glue/bgtc.cpp
-
23src/core/hle/service/glue/bgtc.h
-
16src/core/hle/service/glue/errors.h
-
25src/core/hle/service/glue/glue.cpp
-
16src/core/hle/service/glue/glue.h
-
78src/core/hle/service/glue/manager.cpp
-
63src/core/hle/service/glue/manager.h
-
4src/core/hle/service/service.cpp
@ -1,75 +0,0 @@ |
|||||
// Copyright 2018 yuzu emulator team
|
|
||||
// Licensed under GPLv2 or any later version
|
|
||||
// Refer to the license.txt file included.
|
|
||||
|
|
||||
#include <memory>
|
|
||||
|
|
||||
#include "common/logging/log.h"
|
|
||||
#include "core/hle/ipc_helpers.h"
|
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
|
||||
#include "core/hle/service/arp/arp.h"
|
|
||||
#include "core/hle/service/service.h"
|
|
||||
#include "core/hle/service/sm/sm.h"
|
|
||||
|
|
||||
namespace Service::ARP { |
|
||||
|
|
||||
class ARP_R final : public ServiceFramework<ARP_R> { |
|
||||
public: |
|
||||
explicit ARP_R() : ServiceFramework{"arp:r"} { |
|
||||
// clang-format off
|
|
||||
static const FunctionInfo functions[] = { |
|
||||
{0, nullptr, "GetApplicationLaunchProperty"}, |
|
||||
{1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"}, |
|
||||
{2, nullptr, "GetApplicationControlProperty"}, |
|
||||
{3, nullptr, "GetApplicationControlPropertyWithApplicationId"}, |
|
||||
}; |
|
||||
// clang-format on
|
|
||||
|
|
||||
RegisterHandlers(functions); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
class IRegistrar final : public ServiceFramework<IRegistrar> { |
|
||||
public: |
|
||||
explicit IRegistrar() : ServiceFramework{"IRegistrar"} { |
|
||||
// clang-format off
|
|
||||
static const FunctionInfo functions[] = { |
|
||||
{0, nullptr, "Issue"}, |
|
||||
{1, nullptr, "SetApplicationLaunchProperty"}, |
|
||||
{2, nullptr, "SetApplicationControlProperty"}, |
|
||||
}; |
|
||||
// clang-format on
|
|
||||
|
|
||||
RegisterHandlers(functions); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
class ARP_W final : public ServiceFramework<ARP_W> { |
|
||||
public: |
|
||||
explicit ARP_W() : ServiceFramework{"arp:w"} { |
|
||||
// clang-format off
|
|
||||
static const FunctionInfo functions[] = { |
|
||||
{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, |
|
||||
{1, nullptr, "DeleteProperties"}, |
|
||||
}; |
|
||||
// clang-format on
|
|
||||
|
|
||||
RegisterHandlers(functions); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
void AcquireRegistrar(Kernel::HLERequestContext& ctx) { |
|
||||
LOG_DEBUG(Service_ARP, "called"); |
|
||||
|
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
|
||||
rb.Push(RESULT_SUCCESS); |
|
||||
rb.PushIpcInterface<IRegistrar>(); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
void InstallInterfaces(SM::ServiceManager& sm) { |
|
||||
std::make_shared<ARP_R>()->InstallAsService(sm); |
|
||||
std::make_shared<ARP_W>()->InstallAsService(sm); |
|
||||
} |
|
||||
|
|
||||
} // namespace Service::ARP
|
|
||||
@ -1,16 +0,0 @@ |
|||||
// Copyright 2018 yuzu emulator team |
|
||||
// Licensed under GPLv2 or any later version |
|
||||
// Refer to the license.txt file included. |
|
||||
|
|
||||
#pragma once |
|
||||
|
|
||||
namespace Service::SM { |
|
||||
class ServiceManager; |
|
||||
} |
|
||||
|
|
||||
namespace Service::ARP { |
|
||||
|
|
||||
/// Registers all ARP services with the specified service manager. |
|
||||
void InstallInterfaces(SM::ServiceManager& sm); |
|
||||
|
|
||||
} // namespace Service::ARP |
|
||||
@ -0,0 +1,297 @@ |
|||||
|
// Copyright 2018 yuzu emulator team
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <memory>
|
||||
|
|
||||
|
#include "common/logging/log.h"
|
||||
|
#include "core/file_sys/control_metadata.h"
|
||||
|
#include "core/hle/ipc_helpers.h"
|
||||
|
#include "core/hle/kernel/hle_ipc.h"
|
||||
|
#include "core/hle/kernel/kernel.h"
|
||||
|
#include "core/hle/kernel/process.h"
|
||||
|
#include "core/hle/service/glue/arp.h"
|
||||
|
#include "core/hle/service/glue/errors.h"
|
||||
|
#include "core/hle/service/glue/manager.h"
|
||||
|
#include "core/hle/service/service.h"
|
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
namespace { |
||||
|
std::optional<u64> GetTitleIDForProcessID(const Core::System& system, u64 process_id) { |
||||
|
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()) { |
||||
|
return std::nullopt; |
||||
|
} |
||||
|
|
||||
|
return (*iter)->GetTitleID(); |
||||
|
} |
||||
|
} // Anonymous namespace
|
||||
|
|
||||
|
ARP_R::ARP_R(const Core::System& system, const ARPManager& manager) |
||||
|
: ServiceFramework{"arp:r"}, system(system), manager(manager) { |
||||
|
// clang-format off
|
||||
|
static const FunctionInfo functions[] = { |
||||
|
{0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"}, |
||||
|
{1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"}, |
||||
|
{2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"}, |
||||
|
{3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"}, |
||||
|
}; |
||||
|
// clang-format on
|
||||
|
|
||||
|
RegisterHandlers(functions); |
||||
|
} |
||||
|
|
||||
|
ARP_R::~ARP_R() = default; |
||||
|
|
||||
|
void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { |
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
const auto process_id = rp.PopRaw<u64>(); |
||||
|
|
||||
|
LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); |
||||
|
|
||||
|
const auto title_id = GetTitleIDForProcessID(system, process_id); |
||||
|
if (!title_id.has_value()) { |
||||
|
LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_NOT_REGISTERED); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const auto res = manager.GetLaunchProperty(*title_id); |
||||
|
|
||||
|
if (res.Failed()) { |
||||
|
LOG_ERROR(Service_ARP, "Failed to get launch property!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(res.Code()); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 6}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
rb.PushRaw(*res); |
||||
|
} |
||||
|
|
||||
|
void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { |
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
const auto title_id = rp.PopRaw<u64>(); |
||||
|
|
||||
|
LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id); |
||||
|
|
||||
|
const auto res = manager.GetLaunchProperty(title_id); |
||||
|
|
||||
|
if (res.Failed()) { |
||||
|
LOG_ERROR(Service_ARP, "Failed to get launch property!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(res.Code()); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 6}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
rb.PushRaw(*res); |
||||
|
} |
||||
|
|
||||
|
void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { |
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
const auto process_id = rp.PopRaw<u64>(); |
||||
|
|
||||
|
LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); |
||||
|
|
||||
|
const auto title_id = GetTitleIDForProcessID(system, process_id); |
||||
|
if (!title_id.has_value()) { |
||||
|
LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_NOT_REGISTERED); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const auto res = manager.GetControlProperty(*title_id); |
||||
|
|
||||
|
if (res.Failed()) { |
||||
|
LOG_ERROR(Service_ARP, "Failed to get control property!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(res.Code()); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
ctx.WriteBuffer(*res); |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
} |
||||
|
|
||||
|
void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { |
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
const auto title_id = rp.PopRaw<u64>(); |
||||
|
|
||||
|
LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id); |
||||
|
|
||||
|
const auto res = manager.GetControlProperty(title_id); |
||||
|
|
||||
|
if (res.Failed()) { |
||||
|
LOG_ERROR(Service_ARP, "Failed to get control property!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(res.Code()); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
ctx.WriteBuffer(*res); |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
} |
||||
|
|
||||
|
class IRegistrar final : public ServiceFramework<IRegistrar> { |
||||
|
friend class ARP_W; |
||||
|
|
||||
|
public: |
||||
|
explicit IRegistrar( |
||||
|
std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issuer) |
||||
|
: ServiceFramework{"IRegistrar"}, issue_process_id(std::move(issuer)) { |
||||
|
// clang-format off
|
||||
|
static const FunctionInfo functions[] = { |
||||
|
{0, &IRegistrar::Issue, "Issue"}, |
||||
|
{1, &IRegistrar::SetApplicationLaunchProperty, "SetApplicationLaunchProperty"}, |
||||
|
{2, &IRegistrar::SetApplicationControlProperty, "SetApplicationControlProperty"}, |
||||
|
}; |
||||
|
// clang-format on
|
||||
|
|
||||
|
RegisterHandlers(functions); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
void Issue(Kernel::HLERequestContext& ctx) { |
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
const auto process_id = rp.PopRaw<u64>(); |
||||
|
|
||||
|
LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); |
||||
|
|
||||
|
if (process_id == 0) { |
||||
|
LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_INVALID_PROCESS_ID); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (issued) { |
||||
|
LOG_ERROR(Service_ARP, |
||||
|
"Attempted to issue registrar, but registrar is already issued!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_INVALID_ACCESS); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
issue_process_id(process_id, launch, std::move(control)); |
||||
|
issued = true; |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
} |
||||
|
|
||||
|
void SetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { |
||||
|
LOG_DEBUG(Service_ARP, "called"); |
||||
|
|
||||
|
if (issued) { |
||||
|
LOG_ERROR( |
||||
|
Service_ARP, |
||||
|
"Attempted to set application launch property, but registrar is already issued!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_INVALID_ACCESS); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
launch = rp.PopRaw<ApplicationLaunchProperty>(); |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
} |
||||
|
|
||||
|
void SetApplicationControlProperty(Kernel::HLERequestContext& ctx) { |
||||
|
LOG_DEBUG(Service_ARP, "called"); |
||||
|
|
||||
|
if (issued) { |
||||
|
LOG_ERROR( |
||||
|
Service_ARP, |
||||
|
"Attempted to set application control property, but registrar is already issued!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_INVALID_ACCESS); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
control = ctx.ReadBuffer(); |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
} |
||||
|
|
||||
|
std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issue_process_id; |
||||
|
bool issued = false; |
||||
|
ApplicationLaunchProperty launch; |
||||
|
std::vector<u8> control; |
||||
|
}; |
||||
|
|
||||
|
ARP_W::ARP_W(const Core::System& system, ARPManager& manager) |
||||
|
: ServiceFramework{"arp:w"}, system(system), manager(manager) { |
||||
|
// clang-format off
|
||||
|
static const FunctionInfo functions[] = { |
||||
|
{0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, |
||||
|
{1, &ARP_W::DeleteProperties, "DeleteProperties"}, |
||||
|
}; |
||||
|
// clang-format on
|
||||
|
|
||||
|
RegisterHandlers(functions); |
||||
|
} |
||||
|
|
||||
|
ARP_W::~ARP_W() = default; |
||||
|
|
||||
|
void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { |
||||
|
LOG_DEBUG(Service_ARP, "called"); |
||||
|
|
||||
|
registrar = std::make_shared<IRegistrar>( |
||||
|
[this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { |
||||
|
const auto res = GetTitleIDForProcessID(system, process_id); |
||||
|
if (!res.has_value()) { |
||||
|
return ERR_NOT_REGISTERED; |
||||
|
} |
||||
|
|
||||
|
return manager.Register(*res, launch, std::move(control)); |
||||
|
}); |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
||||
|
rb.Push(RESULT_SUCCESS); |
||||
|
rb.PushIpcInterface(registrar); |
||||
|
} |
||||
|
|
||||
|
void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { |
||||
|
IPC::RequestParser rp{ctx}; |
||||
|
const auto process_id = rp.PopRaw<u64>(); |
||||
|
|
||||
|
LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); |
||||
|
|
||||
|
if (process_id == 0) { |
||||
|
LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_INVALID_PROCESS_ID); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const auto title_id = GetTitleIDForProcessID(system, process_id); |
||||
|
|
||||
|
if (!title_id.has_value()) { |
||||
|
LOG_ERROR(Service_ARP, "No title ID for process ID!"); |
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(ERR_NOT_REGISTERED); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
IPC::ResponseBuilder rb{ctx, 2}; |
||||
|
rb.Push(manager.Unregister(*title_id)); |
||||
|
} |
||||
|
|
||||
|
} // namespace Service::Glue
|
||||
@ -0,0 +1,43 @@ |
|||||
|
// Copyright 2019 yuzu emulator team |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "core/hle/service/service.h" |
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
class ARPManager; |
||||
|
class IRegistrar; |
||||
|
|
||||
|
class ARP_R final : public ServiceFramework<ARP_R> { |
||||
|
public: |
||||
|
explicit ARP_R(const Core::System& system, const ARPManager& manager); |
||||
|
~ARP_R() override; |
||||
|
|
||||
|
private: |
||||
|
void GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx); |
||||
|
void GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx); |
||||
|
void GetApplicationControlProperty(Kernel::HLERequestContext& ctx); |
||||
|
void GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx); |
||||
|
|
||||
|
const Core::System& system; |
||||
|
const ARPManager& manager; |
||||
|
}; |
||||
|
|
||||
|
class ARP_W final : public ServiceFramework<ARP_W> { |
||||
|
public: |
||||
|
explicit ARP_W(const Core::System& system, ARPManager& manager); |
||||
|
~ARP_W() override; |
||||
|
|
||||
|
private: |
||||
|
void AcquireRegistrar(Kernel::HLERequestContext& ctx); |
||||
|
void DeleteProperties(Kernel::HLERequestContext& ctx); |
||||
|
|
||||
|
const Core::System& system; |
||||
|
ARPManager& manager; |
||||
|
std::shared_ptr<IRegistrar> registrar; |
||||
|
}; |
||||
|
|
||||
|
} // namespace Service::Glue |
||||
@ -0,0 +1,50 @@ |
|||||
|
// Copyright 2019 yuzu emulator team
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include "core/hle/service/glue/bgtc.h"
|
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
BGTC_T::BGTC_T() : ServiceFramework{"bgtc:t"} { |
||||
|
// clang-format off
|
||||
|
static const FunctionInfo functions[] = { |
||||
|
{1, nullptr, "NotifyTaskStarting"}, |
||||
|
{2, nullptr, "NotifyTaskFinished"}, |
||||
|
{3, nullptr, "GetTriggerEvent"}, |
||||
|
{4, nullptr, "IsInHalfAwake"}, |
||||
|
{5, nullptr, "NotifyClientName"}, |
||||
|
{6, nullptr, "IsInFullAwake"}, |
||||
|
{11, nullptr, "ScheduleTask"}, |
||||
|
{12, nullptr, "GetScheduledTaskInterval"}, |
||||
|
{13, nullptr, "UnscheduleTask"}, |
||||
|
{14, nullptr, "GetScheduleEvent"}, |
||||
|
{15, nullptr, "SchedulePeriodicTask"}, |
||||
|
{101, nullptr, "GetOperationMode"}, |
||||
|
{102, nullptr, "WillDisconnectNetworkWhenEnteringSleep"}, |
||||
|
{103, nullptr, "WillStayHalfAwakeInsteadSleep"}, |
||||
|
}; |
||||
|
// clang-format on
|
||||
|
|
||||
|
RegisterHandlers(functions); |
||||
|
} |
||||
|
|
||||
|
BGTC_T::~BGTC_T() = default; |
||||
|
|
||||
|
BGTC_SC::BGTC_SC() : ServiceFramework{"bgtc:sc"} { |
||||
|
// clang-format off
|
||||
|
static const FunctionInfo functions[] = { |
||||
|
{1, nullptr, "GetState"}, |
||||
|
{2, nullptr, "GetStateChangedEvent"}, |
||||
|
{3, nullptr, "NotifyEnteringHalfAwake"}, |
||||
|
{4, nullptr, "NotifyLeavingHalfAwake"}, |
||||
|
{5, nullptr, "SetIsUsingSleepUnsupportedDevices"}, |
||||
|
}; |
||||
|
// clang-format on
|
||||
|
|
||||
|
RegisterHandlers(functions); |
||||
|
} |
||||
|
|
||||
|
BGTC_SC::~BGTC_SC() = default; |
||||
|
|
||||
|
} // namespace Service::Glue
|
||||
@ -0,0 +1,23 @@ |
|||||
|
// Copyright 2019 yuzu emulator team |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "core/hle/service/service.h" |
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
class BGTC_T final : public ServiceFramework<BGTC_T> { |
||||
|
public: |
||||
|
BGTC_T(); |
||||
|
~BGTC_T() override; |
||||
|
}; |
||||
|
|
||||
|
class BGTC_SC final : public ServiceFramework<BGTC_SC> { |
||||
|
public: |
||||
|
BGTC_SC(); |
||||
|
~BGTC_SC() override; |
||||
|
}; |
||||
|
|
||||
|
} // namespace Service::Glue |
||||
@ -0,0 +1,16 @@ |
|||||
|
// 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::Glue { |
||||
|
|
||||
|
constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E}; |
||||
|
constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F}; |
||||
|
constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A}; |
||||
|
constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 0x66}; |
||||
|
|
||||
|
} // namespace Service::Glue |
||||
@ -0,0 +1,25 @@ |
|||||
|
// Copyright 2019 yuzu emulator team
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <memory>
|
||||
|
#include "core/core.h"
|
||||
|
#include "core/hle/service/glue/arp.h"
|
||||
|
#include "core/hle/service/glue/bgtc.h"
|
||||
|
#include "core/hle/service/glue/glue.h"
|
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
void InstallInterfaces(Core::System& system) { |
||||
|
// ARP
|
||||
|
std::make_shared<ARP_R>(system, system.GetARPManager()) |
||||
|
->InstallAsService(system.ServiceManager()); |
||||
|
std::make_shared<ARP_W>(system, system.GetARPManager()) |
||||
|
->InstallAsService(system.ServiceManager()); |
||||
|
|
||||
|
// BackGround Task Controller
|
||||
|
std::make_shared<BGTC_T>()->InstallAsService(system.ServiceManager()); |
||||
|
std::make_shared<BGTC_SC>()->InstallAsService(system.ServiceManager()); |
||||
|
} |
||||
|
|
||||
|
} // namespace Service::Glue
|
||||
@ -0,0 +1,16 @@ |
|||||
|
// Copyright 2019 yuzu emulator team |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
namespace Core { |
||||
|
class System; |
||||
|
} // namespace Core |
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
/// Registers all Glue services with the specified service manager. |
||||
|
void InstallInterfaces(Core::System& system); |
||||
|
|
||||
|
} // namespace Service::Glue |
||||
@ -0,0 +1,78 @@ |
|||||
|
// Copyright 2019 yuzu emulator team
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include "core/hle/service/glue/errors.h"
|
||||
|
#include "core/hle/service/glue/manager.h"
|
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
struct ARPManager::MapEntry { |
||||
|
ApplicationLaunchProperty launch; |
||||
|
std::vector<u8> control; |
||||
|
}; |
||||
|
|
||||
|
ARPManager::ARPManager() = default; |
||||
|
|
||||
|
ARPManager::~ARPManager() = default; |
||||
|
|
||||
|
ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const { |
||||
|
if (title_id == 0) { |
||||
|
return ERR_INVALID_PROCESS_ID; |
||||
|
} |
||||
|
|
||||
|
const auto iter = entries.find(title_id); |
||||
|
if (iter == entries.end()) { |
||||
|
return ERR_NOT_REGISTERED; |
||||
|
} |
||||
|
|
||||
|
return MakeResult<ApplicationLaunchProperty>(iter->second.launch); |
||||
|
} |
||||
|
|
||||
|
ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { |
||||
|
if (title_id == 0) { |
||||
|
return ERR_INVALID_PROCESS_ID; |
||||
|
} |
||||
|
|
||||
|
const auto iter = entries.find(title_id); |
||||
|
if (iter == entries.end()) { |
||||
|
return ERR_NOT_REGISTERED; |
||||
|
} |
||||
|
|
||||
|
return MakeResult<std::vector<u8>>(iter->second.control); |
||||
|
} |
||||
|
|
||||
|
ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, |
||||
|
std::vector<u8> control) { |
||||
|
if (title_id == 0) { |
||||
|
return ERR_INVALID_PROCESS_ID; |
||||
|
} |
||||
|
|
||||
|
const auto iter = entries.find(title_id); |
||||
|
if (iter != entries.end()) { |
||||
|
return ERR_INVALID_ACCESS; |
||||
|
} |
||||
|
|
||||
|
entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); |
||||
|
return RESULT_SUCCESS; |
||||
|
} |
||||
|
|
||||
|
ResultCode ARPManager::Unregister(u64 title_id) { |
||||
|
if (title_id == 0) { |
||||
|
return ERR_INVALID_PROCESS_ID; |
||||
|
} |
||||
|
|
||||
|
const auto iter = entries.find(title_id); |
||||
|
if (iter == entries.end()) { |
||||
|
return ERR_NOT_REGISTERED; |
||||
|
} |
||||
|
|
||||
|
entries.erase(iter); |
||||
|
return RESULT_SUCCESS; |
||||
|
} |
||||
|
|
||||
|
void ARPManager::ResetAll() { |
||||
|
entries.clear(); |
||||
|
} |
||||
|
|
||||
|
} // namespace Service::Glue
|
||||
@ -0,0 +1,63 @@ |
|||||
|
// Copyright 2019 yuzu emulator team |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <map> |
||||
|
#include <vector> |
||||
|
#include "common/common_types.h" |
||||
|
#include "core/file_sys/control_metadata.h" |
||||
|
#include "core/file_sys/romfs_factory.h" |
||||
|
#include "core/hle/result.h" |
||||
|
|
||||
|
namespace Service::Glue { |
||||
|
|
||||
|
struct ApplicationLaunchProperty { |
||||
|
u64 title_id; |
||||
|
u32 version; |
||||
|
FileSys::StorageId base_game_storage_id; |
||||
|
FileSys::StorageId update_storage_id; |
||||
|
u8 program_index; |
||||
|
u8 reserved; |
||||
|
}; |
||||
|
static_assert(sizeof(ApplicationLaunchProperty) == 0x10, |
||||
|
"ApplicationLaunchProperty has incorrect size."); |
||||
|
|
||||
|
// A class to manage state related to the arp:w and arp:r services, specifically the registration |
||||
|
// and unregistration of launch and control properties. |
||||
|
class ARPManager { |
||||
|
public: |
||||
|
ARPManager(); |
||||
|
~ARPManager(); |
||||
|
|
||||
|
// Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was |
||||
|
// previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or |
||||
|
// ERR_INVALID_PROCESS_ID if the title ID is 0. |
||||
|
ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const; |
||||
|
|
||||
|
// Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to |
||||
|
// the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was |
||||
|
// never registered or ERR_INVALID_PROCESS_ID if the title ID is 0. |
||||
|
ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const; |
||||
|
|
||||
|
// Adds a new entry to the internal database with the provided parameters, returning |
||||
|
// ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister |
||||
|
// step, and ERR_INVALID_PROCESS_ID if the title ID is 0. |
||||
|
ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); |
||||
|
|
||||
|
// Removes the registration for the provided title ID from the database, returning |
||||
|
// ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the |
||||
|
// title ID is 0. |
||||
|
ResultCode Unregister(u64 title_id); |
||||
|
|
||||
|
// Removes all entries from the database, always succeeds. Should only be used when resetting |
||||
|
// system state. |
||||
|
void ResetAll(); |
||||
|
|
||||
|
private: |
||||
|
struct MapEntry; |
||||
|
std::map<u64, MapEntry> entries; |
||||
|
}; |
||||
|
|
||||
|
} // namespace Service::Glue |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue