commit
4ed2774c26
@ -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
|
Loading…
Reference in New Issue