summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp3
-rw-r--r--src/core/hle/kernel/vm_manager.cpp72
-rw-r--r--src/core/hle/kernel/vm_manager.h8
-rw-r--r--src/core/hle/service/am/am.cpp50
-rw-r--r--src/core/hle/service/am/am.h28
-rw-r--r--src/core/hle/service/am/applet_ae.cpp14
-rw-r--r--src/core/hle/service/am/applet_oe.cpp9
-rw-r--r--src/core/hle/service/am/applets/applets.cpp25
-rw-r--r--src/core/hle/service/am/applets/applets.h17
-rw-r--r--src/core/hle/service/am/applets/error.cpp7
-rw-r--r--src/core/hle/service/am/applets/error.h7
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp13
-rw-r--r--src/core/hle/service/am/applets/general_backend.h12
-rw-r--r--src/core/hle/service/am/applets/profile_select.cpp5
-rw-r--r--src/core/hle/service/am/applets/profile_select.h7
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp5
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h7
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp19
-rw-r--r--src/core/hle/service/am/applets/web_browser.h12
-rw-r--r--src/core/loader/nro.cpp9
-rw-r--r--src/core/loader/nro.h1
21 files changed, 194 insertions, 136 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 20d64f3b0..3d0978cbf 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -104,7 +104,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
return vfs->OpenFile(path, FileSys::Mode::Read);
}
struct System::Impl {
- explicit Impl(System& system) : kernel{system}, cpu_core_manager{system}, reporter{system} {}
+ explicit Impl(System& system)
+ : kernel{system}, cpu_core_manager{system}, applet_manager{system}, reporter{system} {}
Cpu& CurrentCpuCore() {
return cpu_core_manager.GetCurrentCore();
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 40cea1e7c..c7af87073 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -296,12 +296,6 @@ ResultVal<VAddr> VMManager::SetHeapSize(u64 size) {
}
ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
- const auto end_addr = target + size;
- const auto last_addr = end_addr - 1;
- VAddr cur_addr = target;
-
- ResultCode result = RESULT_SUCCESS;
-
// Check how much memory we've already mapped.
const auto mapped_size_result = SizeOfAllocatedVMAsInRange(target, size);
if (mapped_size_result.Failed()) {
@@ -324,13 +318,16 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
// Keep track of the memory regions we unmap.
std::vector<std::pair<u64, u64>> mapped_regions;
+ ResultCode result = RESULT_SUCCESS;
// Iterate, trying to map memory.
{
- cur_addr = target;
+ const auto end_addr = target + size;
+ const auto last_addr = end_addr - 1;
+ VAddr cur_addr = target;
auto iter = FindVMA(target);
- ASSERT_MSG(iter != vma_map.end(), "MapPhysicalMemory iter != end");
+ ASSERT(iter != vma_map.end());
while (true) {
const auto& vma = iter->second;
@@ -342,7 +339,7 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
const auto map_size = std::min(end_addr - cur_addr, vma_end - cur_addr);
if (vma.state == MemoryState::Unmapped) {
const auto map_res =
- MapMemoryBlock(cur_addr, std::make_shared<PhysicalMemory>(map_size, 0), 0,
+ MapMemoryBlock(cur_addr, std::make_shared<PhysicalMemory>(map_size), 0,
map_size, MemoryState::Heap, VMAPermission::ReadWrite);
result = map_res.Code();
if (result.IsError()) {
@@ -360,7 +357,7 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
// Advance to the next block.
cur_addr = vma_end;
iter = FindVMA(cur_addr);
- ASSERT_MSG(iter != vma_map.end(), "MapPhysicalMemory iter != end");
+ ASSERT(iter != vma_map.end());
}
}
@@ -368,7 +365,7 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
if (result.IsError()) {
for (const auto [unmap_address, unmap_size] : mapped_regions) {
ASSERT_MSG(UnmapRange(unmap_address, unmap_size).IsSuccess(),
- "MapPhysicalMemory un-map on error");
+ "Failed to unmap memory range.");
}
return result;
@@ -381,12 +378,6 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
}
ResultCode VMManager::UnmapPhysicalMemory(VAddr target, u64 size) {
- const auto end_addr = target + size;
- const auto last_addr = end_addr - 1;
- VAddr cur_addr = target;
-
- ResultCode result = RESULT_SUCCESS;
-
// Check how much memory is currently mapped.
const auto mapped_size_result = SizeOfUnmappablePhysicalMemoryInRange(target, size);
if (mapped_size_result.Failed()) {
@@ -401,13 +392,16 @@ ResultCode VMManager::UnmapPhysicalMemory(VAddr target, u64 size) {
// Keep track of the memory regions we unmap.
std::vector<std::pair<u64, u64>> unmapped_regions;
+ ResultCode result = RESULT_SUCCESS;
// Try to unmap regions.
{
- cur_addr = target;
+ const auto end_addr = target + size;
+ const auto last_addr = end_addr - 1;
+ VAddr cur_addr = target;
auto iter = FindVMA(target);
- ASSERT_MSG(iter != vma_map.end(), "UnmapPhysicalMemory iter != end");
+ ASSERT(iter != vma_map.end());
while (true) {
const auto& vma = iter->second;
@@ -434,7 +428,7 @@ ResultCode VMManager::UnmapPhysicalMemory(VAddr target, u64 size) {
// Advance to the next block.
cur_addr = vma_end;
iter = FindVMA(cur_addr);
- ASSERT_MSG(iter != vma_map.end(), "UnmapPhysicalMemory iter != end");
+ ASSERT(iter != vma_map.end());
}
}
@@ -443,10 +437,12 @@ ResultCode VMManager::UnmapPhysicalMemory(VAddr target, u64 size) {
if (result.IsError()) {
for (const auto [map_address, map_size] : unmapped_regions) {
const auto remap_res =
- MapMemoryBlock(map_address, std::make_shared<PhysicalMemory>(map_size, 0), 0,
- map_size, MemoryState::Heap, VMAPermission::None);
- ASSERT_MSG(remap_res.Succeeded(), "UnmapPhysicalMemory re-map on error");
+ MapMemoryBlock(map_address, std::make_shared<PhysicalMemory>(map_size), 0, map_size,
+ MemoryState::Heap, VMAPermission::None);
+ ASSERT_MSG(remap_res.Succeeded(), "Failed to remap a memory block.");
}
+
+ return result;
}
// Update mapped amount
@@ -757,20 +753,26 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre
// Always merge allocated memory blocks, even when they don't share the same backing block.
if (left.type == VMAType::AllocatedMemoryBlock &&
(left.backing_block != right.backing_block || left.offset + left.size != right.offset)) {
+ const auto right_begin = right.backing_block->begin() + right.offset;
+ const auto right_end = right_begin + right.size;
+
// Check if we can save work.
if (left.offset == 0 && left.size == left.backing_block->size()) {
// Fast case: left is an entire backing block.
- left.backing_block->insert(left.backing_block->end(),
- right.backing_block->begin() + right.offset,
- right.backing_block->begin() + right.offset + right.size);
+ left.backing_block->insert(left.backing_block->end(), right_begin, right_end);
} else {
// Slow case: make a new memory block for left and right.
+ const auto left_begin = left.backing_block->begin() + left.offset;
+ const auto left_end = left_begin + left.size;
+ const auto left_size = static_cast<std::size_t>(std::distance(left_begin, left_end));
+ const auto right_size = static_cast<std::size_t>(std::distance(right_begin, right_end));
+
auto new_memory = std::make_shared<PhysicalMemory>();
- new_memory->insert(new_memory->end(), left.backing_block->begin() + left.offset,
- left.backing_block->begin() + left.offset + left.size);
- new_memory->insert(new_memory->end(), right.backing_block->begin() + right.offset,
- right.backing_block->begin() + right.offset + right.size);
- left.backing_block = new_memory;
+ new_memory->reserve(left_size + right_size);
+ new_memory->insert(new_memory->end(), left_begin, left_end);
+ new_memory->insert(new_memory->end(), right_begin, right_end);
+
+ left.backing_block = std::move(new_memory);
left.offset = 0;
}
@@ -965,7 +967,7 @@ ResultVal<std::size_t> VMManager::SizeOfAllocatedVMAsInRange(VAddr address,
VAddr cur_addr = address;
auto iter = FindVMA(cur_addr);
- ASSERT_MSG(iter != vma_map.end(), "SizeOfAllocatedVMAsInRange iter != end");
+ ASSERT(iter != vma_map.end());
while (true) {
const auto& vma = iter->second;
@@ -986,7 +988,7 @@ ResultVal<std::size_t> VMManager::SizeOfAllocatedVMAsInRange(VAddr address,
// Advance to the next block.
cur_addr = vma_end;
iter = std::next(iter);
- ASSERT_MSG(iter != vma_map.end(), "SizeOfAllocatedVMAsInRange iter != end");
+ ASSERT(iter != vma_map.end());
}
return MakeResult(mapped_size);
@@ -1000,7 +1002,7 @@ ResultVal<std::size_t> VMManager::SizeOfUnmappablePhysicalMemoryInRange(VAddr ad
VAddr cur_addr = address;
auto iter = FindVMA(cur_addr);
- ASSERT_MSG(iter != vma_map.end(), "SizeOfUnmappablePhysicalMemoryInRange iter != end");
+ ASSERT(iter != vma_map.end());
while (true) {
const auto& vma = iter->second;
@@ -1029,7 +1031,7 @@ ResultVal<std::size_t> VMManager::SizeOfUnmappablePhysicalMemoryInRange(VAddr ad
// Advance to the next block.
cur_addr = vma_end;
iter = std::next(iter);
- ASSERT_MSG(iter != vma_map.end(), "SizeOfUnmappablePhysicalMemoryInRange iter != end");
+ ASSERT(iter != vma_map.end());
}
return MakeResult(mapped_size);
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index b18cde619..850a7ebc3 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -454,8 +454,8 @@ public:
/// Maps memory at a given address.
///
- /// @param addr The virtual address to map memory at.
- /// @param size The amount of memory to map.
+ /// @param target The virtual address to map memory at.
+ /// @param size The amount of memory to map.
///
/// @note The destination address must lie within the Map region.
///
@@ -468,8 +468,8 @@ public:
/// Unmaps memory at a given address.
///
- /// @param addr The virtual address to unmap memory at.
- /// @param size The amount of memory to unmap.
+ /// @param target The virtual address to unmap memory at.
+ /// @param size The amount of memory to unmap.
///
/// @note The destination address must lie within the Map region.
///
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 111633ba3..aa2c83937 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -56,7 +56,8 @@ struct LaunchParameters {
};
static_assert(sizeof(LaunchParameters) == 0x88);
-IWindowController::IWindowController() : ServiceFramework("IWindowController") {
+IWindowController::IWindowController(Core::System& system_)
+ : ServiceFramework("IWindowController"), system{system_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CreateWindow"},
@@ -75,7 +76,7 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") {
IWindowController::~IWindowController() = default;
void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
- const u64 process_id = Core::System::GetInstance().Kernel().CurrentProcess()->GetProcessID();
+ const u64 process_id = system.CurrentProcess()->GetProcessID();
LOG_DEBUG(Service_AM, "called. Process ID=0x{:016X}", process_id);
@@ -231,8 +232,9 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
IDebugFunctions::~IDebugFunctions() = default;
-ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
+ISelfController::ISelfController(Core::System& system_,
+ std::shared_ptr<NVFlinger::NVFlinger> nvflinger_)
+ : ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger_)) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Exit"},
@@ -280,7 +282,7 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
RegisterHandlers(functions);
- auto& kernel = Core::System::GetInstance().Kernel();
+ auto& kernel = system_.Kernel();
launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
"ISelfController:LaunchableEvent");
@@ -501,8 +503,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
rb.PushCopyObjects(accumulated_suspended_tick_changed_event.readable);
}
-AppletMessageQueue::AppletMessageQueue() {
- auto& kernel = Core::System::GetInstance().Kernel();
+AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
"AMMessageQueue:OnMessageRecieved");
on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair(
@@ -937,9 +938,8 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
-ILibraryAppletCreator::ILibraryAppletCreator(u64 current_process_title_id)
- : ServiceFramework("ILibraryAppletCreator"),
- current_process_title_id(current_process_title_id) {
+ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
+ : ServiceFramework("ILibraryAppletCreator"), system{system_} {
static const FunctionInfo functions[] = {
{0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
{1, nullptr, "TerminateAllLibraryApplets"},
@@ -961,8 +961,8 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}",
static_cast<u32>(applet_id), applet_mode);
- const auto& applet_manager{Core::System::GetInstance().GetAppletManager()};
- const auto applet = applet_manager.GetApplet(applet_id, current_process_title_id);
+ const auto& applet_manager{system.GetAppletManager()};
+ const auto applet = applet_manager.GetApplet(applet_id);
if (applet == nullptr) {
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast<u32>(applet_id));
@@ -999,8 +999,7 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
const auto handle{rp.Pop<Kernel::Handle>()};
const auto transfer_mem =
- Core::System::GetInstance().CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(
- handle);
+ system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
if (transfer_mem == nullptr) {
LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
@@ -1018,7 +1017,8 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
rb.PushIpcInterface(std::make_shared<IStorage>(std::move(memory)));
}
-IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
+IApplicationFunctions::IApplicationFunctions(Core::System& system_)
+ : ServiceFramework("IApplicationFunctions"), system{system_} {
// clang-format off
static const FunctionInfo functions[] = {
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
@@ -1180,7 +1180,7 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
// Get supported languages from NACP, if possible
// Default to 0 (all languages supported)
u32 supported_languages = 0;
- FileSys::PatchManager pm{Core::System::GetInstance().CurrentProcess()->GetTitleID()};
+ FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
const auto res = pm.GetControlMetadata();
if (res.first != nullptr) {
@@ -1188,8 +1188,8 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
}
// Call IApplicationManagerInterface implementation.
- auto& service_manager = Core::System::GetInstance().ServiceManager();
- auto ns_am2 = service_manager.GetService<Service::NS::NS>("ns:am2");
+ auto& service_manager = system.ServiceManager();
+ auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
auto app_man = ns_am2->GetApplicationManagerInterface();
// Get desired application language
@@ -1261,8 +1261,8 @@ void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
"new_journal={:016X}",
static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size);
- FileSystem::WriteSaveDataSize(type, Core::CurrentProcess()->GetTitleID(), user_id,
- {new_normal_size, new_journal_size});
+ const auto title_id = system.CurrentProcess()->GetTitleID();
+ FileSystem::WriteSaveDataSize(type, title_id, user_id, {new_normal_size, new_journal_size});
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
@@ -1281,8 +1281,8 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast<u8>(type),
user_id[1], user_id[0]);
- const auto size =
- FileSystem::ReadSaveDataSize(type, Core::CurrentProcess()->GetTitleID(), user_id);
+ const auto title_id = system.CurrentProcess()->GetTitleID();
+ const auto size = FileSystem::ReadSaveDataSize(type, title_id, user_id);
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
@@ -1300,9 +1300,9 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system) {
- auto message_queue = std::make_shared<AppletMessageQueue>();
- message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); // Needed on
- // game boot
+ auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel());
+ // Needed on game boot
+ message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager);
std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index cbc9da7b6..28f870302 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -10,12 +10,15 @@
#include "core/hle/kernel/writable_event.h"
#include "core/hle/service/service.h"
-namespace Service {
-namespace NVFlinger {
+namespace Kernel {
+class KernelCore;
+}
+
+namespace Service::NVFlinger {
class NVFlinger;
}
-namespace AM {
+namespace Service::AM {
enum SystemLanguage {
Japanese = 0,
@@ -47,7 +50,7 @@ public:
PerformanceModeChanged = 31,
};
- AppletMessageQueue();
+ explicit AppletMessageQueue(Kernel::KernelCore& kernel);
~AppletMessageQueue();
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const;
@@ -65,12 +68,14 @@ private:
class IWindowController final : public ServiceFramework<IWindowController> {
public:
- IWindowController();
+ explicit IWindowController(Core::System& system_);
~IWindowController() override;
private:
void GetAppletResourceUserId(Kernel::HLERequestContext& ctx);
void AcquireForegroundRights(Kernel::HLERequestContext& ctx);
+
+ Core::System& system;
};
class IAudioController final : public ServiceFramework<IAudioController> {
@@ -113,7 +118,8 @@ public:
class ISelfController final : public ServiceFramework<ISelfController> {
public:
- explicit ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
+ explicit ISelfController(Core::System& system_,
+ std::shared_ptr<NVFlinger::NVFlinger> nvflinger_);
~ISelfController() override;
private:
@@ -208,7 +214,7 @@ private:
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
public:
- ILibraryAppletCreator(u64 current_process_title_id);
+ explicit ILibraryAppletCreator(Core::System& system_);
~ILibraryAppletCreator() override;
private:
@@ -216,12 +222,12 @@ private:
void CreateStorage(Kernel::HLERequestContext& ctx);
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
- u64 current_process_title_id;
+ Core::System& system;
};
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
public:
- IApplicationFunctions();
+ explicit IApplicationFunctions(Core::System& system_);
~IApplicationFunctions() override;
private:
@@ -245,6 +251,7 @@ private:
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
Kernel::EventPair gpu_error_detected_event;
+ Core::System& system;
};
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
@@ -278,5 +285,4 @@ public:
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger, Core::System& system);
-} // namespace AM
-} // namespace Service
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index a34368c8b..e454b77d8 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -50,7 +50,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ISelfController>(nvflinger);
+ rb.PushIpcInterface<ISelfController>(system, nvflinger);
}
void GetWindowController(Kernel::HLERequestContext& ctx) {
@@ -58,7 +58,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IWindowController>();
+ rb.PushIpcInterface<IWindowController>(system);
}
void GetAudioController(Kernel::HLERequestContext& ctx) {
@@ -98,7 +98,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ILibraryAppletCreator>(system.CurrentProcess()->GetTitleID());
+ rb.PushIpcInterface<ILibraryAppletCreator>(system);
}
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
@@ -106,7 +106,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IApplicationFunctions>();
+ rb.PushIpcInterface<IApplicationFunctions>(system);
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
@@ -154,7 +154,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ISelfController>(nvflinger);
+ rb.PushIpcInterface<ISelfController>(system, nvflinger);
}
void GetWindowController(Kernel::HLERequestContext& ctx) {
@@ -162,7 +162,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IWindowController>();
+ rb.PushIpcInterface<IWindowController>(system);
}
void GetAudioController(Kernel::HLERequestContext& ctx) {
@@ -194,7 +194,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ILibraryAppletCreator>(system.CurrentProcess()->GetTitleID());
+ rb.PushIpcInterface<ILibraryAppletCreator>(system);
}
void GetHomeMenuFunctions(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 5d53ef113..a2ffaa440 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -4,7 +4,6 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/process.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_oe.h"
#include "core/hle/service/nvflinger/nvflinger.h"
@@ -64,7 +63,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IWindowController>();
+ rb.PushIpcInterface<IWindowController>(system);
}
void GetSelfController(Kernel::HLERequestContext& ctx) {
@@ -72,7 +71,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ISelfController>(nvflinger);
+ rb.PushIpcInterface<ISelfController>(system, nvflinger);
}
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
@@ -88,7 +87,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ILibraryAppletCreator>(system.CurrentProcess()->GetTitleID());
+ rb.PushIpcInterface<ILibraryAppletCreator>(system);
}
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
@@ -96,7 +95,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IApplicationFunctions>();
+ rb.PushIpcInterface<IApplicationFunctions>(system);
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 6bdba2468..d2e35362f 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -23,8 +23,7 @@
namespace Service::AM::Applets {
-AppletDataBroker::AppletDataBroker() {
- auto& kernel = Core::System::GetInstance().Kernel();
+AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) {
state_changed_event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:StateChangedEvent");
pop_out_data_event = Kernel::WritableEvent::CreateEventPair(
@@ -121,7 +120,7 @@ Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent(
return state_changed_event.readable;
}
-Applet::Applet() = default;
+Applet::Applet(Kernel::KernelCore& kernel_) : broker{kernel_} {}
Applet::~Applet() = default;
@@ -154,7 +153,7 @@ AppletFrontendSet::AppletFrontendSet(AppletFrontendSet&&) noexcept = default;
AppletFrontendSet& AppletFrontendSet::operator=(AppletFrontendSet&&) noexcept = default;
-AppletManager::AppletManager() = default;
+AppletManager::AppletManager(Core::System& system_) : system{system_} {}
AppletManager::~AppletManager() = default;
@@ -216,28 +215,28 @@ void AppletManager::ClearAll() {
frontend = {};
}
-std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, u64 current_process_title_id) const {
+std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const {
switch (id) {
case AppletId::Auth:
- return std::make_shared<Auth>(*frontend.parental_controls);
+ return std::make_shared<Auth>(system, *frontend.parental_controls);
case AppletId::Error:
- return std::make_shared<Error>(*frontend.error);
+ return std::make_shared<Error>(system, *frontend.error);
case AppletId::ProfileSelect:
- return std::make_shared<ProfileSelect>(*frontend.profile_select);
+ return std::make_shared<ProfileSelect>(system, *frontend.profile_select);
case AppletId::SoftwareKeyboard:
- return std::make_shared<SoftwareKeyboard>(*frontend.software_keyboard);
+ return std::make_shared<SoftwareKeyboard>(system, *frontend.software_keyboard);
case AppletId::PhotoViewer:
- return std::make_shared<PhotoViewer>(*frontend.photo_viewer);
+ return std::make_shared<PhotoViewer>(system, *frontend.photo_viewer);
case AppletId::LibAppletShop:
- return std::make_shared<WebBrowser>(*frontend.web_browser, current_process_title_id,
+ return std::make_shared<WebBrowser>(system, *frontend.web_browser,
frontend.e_commerce.get());
case AppletId::LibAppletOff:
- return std::make_shared<WebBrowser>(*frontend.web_browser, current_process_title_id);
+ return std::make_shared<WebBrowser>(system, *frontend.web_browser);
default:
UNIMPLEMENTED_MSG(
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
static_cast<u8>(id));
- return std::make_shared<StubApplet>(id);
+ return std::make_shared<StubApplet>(system, id);
}
}
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index adc973dad..764c3418c 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -12,6 +12,10 @@
union ResultCode;
+namespace Core {
+class System;
+}
+
namespace Core::Frontend {
class ECommerceApplet;
class ErrorApplet;
@@ -22,6 +26,10 @@ class SoftwareKeyboardApplet;
class WebBrowserApplet;
} // namespace Core::Frontend
+namespace Kernel {
+class KernelCore;
+}
+
namespace Service::AM {
class IStorage;
@@ -53,7 +61,7 @@ enum class AppletId : u32 {
class AppletDataBroker final {
public:
- AppletDataBroker();
+ explicit AppletDataBroker(Kernel::KernelCore& kernel_);
~AppletDataBroker();
struct RawChannelData {
@@ -108,7 +116,7 @@ private:
class Applet {
public:
- Applet();
+ explicit Applet(Kernel::KernelCore& kernel_);
virtual ~Applet();
virtual void Initialize();
@@ -179,7 +187,7 @@ struct AppletFrontendSet {
class AppletManager {
public:
- AppletManager();
+ explicit AppletManager(Core::System& system_);
~AppletManager();
void SetAppletFrontendSet(AppletFrontendSet set);
@@ -187,10 +195,11 @@ public:
void SetDefaultAppletsIfMissing();
void ClearAll();
- std::shared_ptr<Applet> GetApplet(AppletId id, u64 current_process_title_id) const;
+ std::shared_ptr<Applet> GetApplet(AppletId id) const;
private:
AppletFrontendSet frontend;
+ Core::System& system;
};
} // namespace Applets
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
index af3a900f8..a7db26725 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -85,7 +85,8 @@ ResultCode Decode64BitError(u64 error) {
} // Anonymous namespace
-Error::Error(const Core::Frontend::ErrorApplet& frontend) : frontend(frontend) {}
+Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_)
+ : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
Error::~Error() = default;
@@ -145,8 +146,8 @@ void Error::Execute() {
}
const auto callback = [this] { DisplayCompleted(); };
- const auto title_id = Core::CurrentProcess()->GetTitleID();
- const auto& reporter{Core::System::GetInstance().GetReporter()};
+ const auto title_id = system.CurrentProcess()->GetTitleID();
+ const auto& reporter{system.GetReporter()};
switch (mode) {
case ErrorAppletMode::ShowError:
diff --git a/src/core/hle/service/am/applets/error.h b/src/core/hle/service/am/applets/error.h
index a3590d181..a105cdb0c 100644
--- a/src/core/hle/service/am/applets/error.h
+++ b/src/core/hle/service/am/applets/error.h
@@ -7,6 +7,10 @@
#include "core/hle/result.h"
#include "core/hle/service/am/applets/applets.h"
+namespace Core {
+class System;
+}
+
namespace Service::AM::Applets {
enum class ErrorAppletMode : u8 {
@@ -21,7 +25,7 @@ enum class ErrorAppletMode : u8 {
class Error final : public Applet {
public:
- explicit Error(const Core::Frontend::ErrorApplet& frontend);
+ explicit Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_);
~Error() override;
void Initialize() override;
@@ -42,6 +46,7 @@ private:
std::unique_ptr<ErrorArguments> args;
bool complete = false;
+ Core::System& system;
};
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp
index e0def8dff..328438a1d 100644
--- a/src/core/hle/service/am/applets/general_backend.cpp
+++ b/src/core/hle/service/am/applets/general_backend.cpp
@@ -37,7 +37,8 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
}
}
-Auth::Auth(Core::Frontend::ParentalControlsApplet& frontend) : frontend(frontend) {}
+Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_)
+ : Applet{system_.Kernel()}, frontend(frontend_) {}
Auth::~Auth() = default;
@@ -151,7 +152,8 @@ void Auth::AuthFinished(bool successful) {
broker.SignalStateChanged();
}
-PhotoViewer::PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend) : frontend(frontend) {}
+PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_)
+ : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
PhotoViewer::~PhotoViewer() = default;
@@ -185,7 +187,7 @@ void PhotoViewer::Execute() {
const auto callback = [this] { ViewFinished(); };
switch (mode) {
case PhotoViewerAppletMode::CurrentApp:
- frontend.ShowPhotosForApplication(Core::CurrentProcess()->GetTitleID(), callback);
+ frontend.ShowPhotosForApplication(system.CurrentProcess()->GetTitleID(), callback);
break;
case PhotoViewerAppletMode::AllApps:
frontend.ShowAllPhotos(callback);
@@ -200,7 +202,8 @@ void PhotoViewer::ViewFinished() {
broker.SignalStateChanged();
}
-StubApplet::StubApplet(AppletId id) : id(id) {}
+StubApplet::StubApplet(Core::System& system_, AppletId id_)
+ : Applet{system_.Kernel()}, id(id_), system{system_} {}
StubApplet::~StubApplet() = default;
@@ -209,7 +212,7 @@ void StubApplet::Initialize() {
Applet::Initialize();
const auto data = broker.PeekDataToAppletForDebug();
- Core::System::GetInstance().GetReporter().SaveUnimplementedAppletReport(
+ system.GetReporter().SaveUnimplementedAppletReport(
static_cast<u32>(id), common_args.arguments_version, common_args.library_version,
common_args.theme_color, common_args.play_startup_sound, common_args.system_tick,
data.normal, data.interactive);
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h
index 0da252044..cfa2df369 100644
--- a/src/core/hle/service/am/applets/general_backend.h
+++ b/src/core/hle/service/am/applets/general_backend.h
@@ -6,6 +6,10 @@
#include "core/hle/service/am/applets/applets.h"
+namespace Core {
+class System;
+}
+
namespace Service::AM::Applets {
enum class AuthAppletType : u32 {
@@ -16,7 +20,7 @@ enum class AuthAppletType : u32 {
class Auth final : public Applet {
public:
- explicit Auth(Core::Frontend::ParentalControlsApplet& frontend);
+ explicit Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_);
~Auth() override;
void Initialize() override;
@@ -45,7 +49,7 @@ enum class PhotoViewerAppletMode : u8 {
class PhotoViewer final : public Applet {
public:
- explicit PhotoViewer(const Core::Frontend::PhotoViewerApplet& frontend);
+ explicit PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_);
~PhotoViewer() override;
void Initialize() override;
@@ -60,11 +64,12 @@ private:
const Core::Frontend::PhotoViewerApplet& frontend;
bool complete = false;
PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
+ Core::System& system;
};
class StubApplet final : public Applet {
public:
- explicit StubApplet(AppletId id);
+ explicit StubApplet(Core::System& system_, AppletId id_);
~StubApplet() override;
void Initialize() override;
@@ -76,6 +81,7 @@ public:
private:
AppletId id;
+ Core::System& system;
};
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp
index 57b5419e8..3eba696ca 100644
--- a/src/core/hle/service/am/applets/profile_select.cpp
+++ b/src/core/hle/service/am/applets/profile_select.cpp
@@ -15,8 +15,9 @@ namespace Service::AM::Applets {
constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
-ProfileSelect::ProfileSelect(const Core::Frontend::ProfileSelectApplet& frontend)
- : frontend(frontend) {}
+ProfileSelect::ProfileSelect(Core::System& system_,
+ const Core::Frontend::ProfileSelectApplet& frontend_)
+ : Applet{system_.Kernel()}, frontend(frontend_) {}
ProfileSelect::~ProfileSelect() = default;
diff --git a/src/core/hle/service/am/applets/profile_select.h b/src/core/hle/service/am/applets/profile_select.h
index 563cd744a..16364ead7 100644
--- a/src/core/hle/service/am/applets/profile_select.h
+++ b/src/core/hle/service/am/applets/profile_select.h
@@ -11,6 +11,10 @@
#include "core/hle/result.h"
#include "core/hle/service/am/applets/applets.h"
+namespace Core {
+class System;
+}
+
namespace Service::AM::Applets {
struct UserSelectionConfig {
@@ -29,7 +33,8 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco
class ProfileSelect final : public Applet {
public:
- explicit ProfileSelect(const Core::Frontend::ProfileSelectApplet& frontend);
+ explicit ProfileSelect(Core::System& system_,
+ const Core::Frontend::ProfileSelectApplet& frontend_);
~ProfileSelect() override;
void Initialize() override;
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index e197990f7..748559cd0 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -39,8 +39,9 @@ static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
return params;
}
-SoftwareKeyboard::SoftwareKeyboard(const Core::Frontend::SoftwareKeyboardApplet& frontend)
- : frontend(frontend) {}
+SoftwareKeyboard::SoftwareKeyboard(Core::System& system_,
+ const Core::Frontend::SoftwareKeyboardApplet& frontend_)
+ : Applet{system_.Kernel()}, frontend(frontend_) {}
SoftwareKeyboard::~SoftwareKeyboard() = default;
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index 0fbc43e51..ef4801fc6 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -16,6 +16,10 @@
union ResultCode;
+namespace Core {
+class System;
+}
+
namespace Service::AM::Applets {
enum class KeysetDisable : u32 {
@@ -55,7 +59,8 @@ static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect siz
class SoftwareKeyboard final : public Applet {
public:
- explicit SoftwareKeyboard(const Core::Frontend::SoftwareKeyboardApplet& frontend);
+ explicit SoftwareKeyboard(Core::System& system_,
+ const Core::Frontend::SoftwareKeyboardApplet& frontend_);
~SoftwareKeyboard() override;
void Initialize() override;
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index f3c9fef0e..32283e819 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -190,8 +190,9 @@ std::map<WebArgTLVType, std::vector<u8>> GetWebArguments(const std::vector<u8>&
return out;
}
-FileSys::VirtualFile GetApplicationRomFS(u64 title_id, FileSys::ContentRecordType type) {
- const auto& installed{Core::System::GetInstance().GetContentProvider()};
+FileSys::VirtualFile GetApplicationRomFS(const Core::System& system, u64 title_id,
+ FileSys::ContentRecordType type) {
+ const auto& installed{system.GetContentProvider()};
const auto res = installed.GetEntry(title_id, type);
if (res != nullptr) {
@@ -207,10 +208,10 @@ FileSys::VirtualFile GetApplicationRomFS(u64 title_id, FileSys::ContentRecordTyp
} // Anonymous namespace
-WebBrowser::WebBrowser(Core::Frontend::WebBrowserApplet& frontend, u64 current_process_title_id,
- Core::Frontend::ECommerceApplet* frontend_e_commerce)
- : frontend(frontend), frontend_e_commerce(frontend_e_commerce),
- current_process_title_id(current_process_title_id) {}
+WebBrowser::WebBrowser(Core::System& system_, Core::Frontend::WebBrowserApplet& frontend_,
+ Core::Frontend::ECommerceApplet* frontend_e_commerce_)
+ : Applet{system_.Kernel()}, frontend(frontend_),
+ frontend_e_commerce(frontend_e_commerce_), system{system_} {}
WebBrowser::~WebBrowser() = default;
@@ -266,7 +267,7 @@ void WebBrowser::UnpackRomFS() {
ASSERT(offline_romfs != nullptr);
const auto dir =
FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard);
- const auto& vfs{Core::System::GetInstance().GetFilesystem()};
+ const auto& vfs{system.GetFilesystem()};
const auto temp_dir = vfs->CreateDirectory(temporary_dir, FileSys::Mode::ReadWrite);
FileSys::VfsRawCopyD(dir, temp_dir);
@@ -470,10 +471,10 @@ void WebBrowser::InitializeOffline() {
}
if (title_id == 0) {
- title_id = current_process_title_id;
+ title_id = system.CurrentProcess()->GetTitleID();
}
- offline_romfs = GetApplicationRomFS(title_id, type);
+ offline_romfs = GetApplicationRomFS(system, title_id, type);
if (offline_romfs == nullptr) {
status = ResultCode(-1);
LOG_ERROR(Service_AM, "Failed to find offline data for request!");
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h
index 870f57b64..8d4027411 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -9,6 +9,10 @@
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/applets.h"
+namespace Core {
+class System;
+}
+
namespace Service::AM::Applets {
enum class ShimKind : u32;
@@ -17,8 +21,8 @@ enum class WebArgTLVType : u16;
class WebBrowser final : public Applet {
public:
- WebBrowser(Core::Frontend::WebBrowserApplet& frontend, u64 current_process_title_id,
- Core::Frontend::ECommerceApplet* frontend_e_commerce = nullptr);
+ WebBrowser(Core::System& system_, Core::Frontend::WebBrowserApplet& frontend_,
+ Core::Frontend::ECommerceApplet* frontend_e_commerce_ = nullptr);
~WebBrowser() override;
@@ -59,8 +63,6 @@ private:
bool unpacked = false;
ResultCode status = RESULT_SUCCESS;
- u64 current_process_title_id;
-
ShimKind kind;
std::map<WebArgTLVType, std::vector<u8>> args;
@@ -74,6 +76,8 @@ private:
std::optional<u128> user_id;
std::optional<bool> shop_full_display;
std::string shop_extra_parameter;
+
+ Core::System& system;
};
} // namespace Service::AM::Applets
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index e92e2e06e..3a5361fdd 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -258,6 +258,15 @@ ResultStatus AppLoader_NRO::ReadTitle(std::string& title) {
return ResultStatus::Success;
}
+ResultStatus AppLoader_NRO::ReadControlData(FileSys::NACP& control) {
+ if (nacp == nullptr) {
+ return ResultStatus::ErrorNoControl;
+ }
+
+ control = *nacp;
+ return ResultStatus::Success;
+}
+
bool AppLoader_NRO::IsRomFSUpdatable() const {
return false;
}
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h
index 1ffdae805..71811bc29 100644
--- a/src/core/loader/nro.h
+++ b/src/core/loader/nro.h
@@ -43,6 +43,7 @@ public:
ResultStatus ReadProgramId(u64& out_program_id) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
ResultStatus ReadTitle(std::string& title) override;
+ ResultStatus ReadControlData(FileSys::NACP& control) override;
bool IsRomFSUpdatable() const override;
private: