Add more missing services

This commit is contained in:
collecting
2026-02-04 06:37:06 -05:00
parent d18df2919b
commit 75dfdce858
12 changed files with 168 additions and 25 deletions

View File

@@ -5,18 +5,22 @@
#include "common/uuid.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/nca_metadata.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/process_creation.h"
#include "core/hle/service/am/applet_data_broker.h"
#include "core/hle/service/am/applet_manager.h"
#include "core/hle/service/am/frontend/applet_cabinet.h"
#include "core/hle/service/am/frontend/applet_controller.h"
#include "core/hle/service/am/frontend/applet_mii_edit_types.h"
#include "core/hle/service/am/frontend/applet_software_keyboard_types.h"
#include "core/hle/service/am/process_creation.h"
#include "core/hle/service/am/service/storage.h"
#include "core/hle/service/am/window_system.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "hid_core/hid_types.h"
namespace Service::AM {
namespace {
@@ -264,8 +268,10 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
m_cv.wait(lk, [&] { return m_pending_process != nullptr; });
if (true && m_window_system->GetOverlayDisplayApplet() == nullptr) {
if (auto overlay_process = CreateProcess(m_system, static_cast<u64>(AppletProgramId::OverlayDisplay), 0, 0)) {
auto overlay_applet = std::make_shared<Applet>(m_system, std::move(overlay_process), false);
if (auto overlay_process =
CreateProcess(m_system, static_cast<u64>(AppletProgramId::OverlayDisplay), 0, 0)) {
auto overlay_applet =
std::make_shared<Applet>(m_system, std::move(overlay_process), false);
overlay_applet->program_id = static_cast<u64>(AppletProgramId::OverlayDisplay);
overlay_applet->applet_id = AppletId::OverlayDisplay;
overlay_applet->type = AppletType::OverlayApplet;
@@ -275,7 +281,8 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
overlay_applet->home_button_long_pressed_blocked = false;
m_window_system->TrackApplet(overlay_applet, false);
overlay_applet->process->Run();
LOG_INFO(Service_AM, "called, Overlay applet launched before application (initially hidden, watching home button)");
LOG_INFO(Service_AM, "called, Overlay applet launched before application (initially "
"hidden, watching home button)");
}
}
@@ -291,6 +298,37 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
// Push UserChannel data from previous application
if (params.launch_type == LaunchType::ApplicationInitiated) {
applet->user_channel_launch_parameter.swap(m_system.GetUserChannel());
// Register game NCAs for QLaunch DLC support
m_manual_provider.ClearAllEntries();
const auto title_id = params.program_id;
auto& system_provider = m_system.GetContentProviderUnion();
LOG_INFO(Service_AM, "QLaunch Support: Registering NCAs for title_id={:016X}", title_id);
// Register Program NCA
auto game_nca = system_provider.GetEntry(title_id, FileSys::ContentRecordType::Program);
if (game_nca) {
m_manual_provider.AddEntry(FileSys::TitleType::Application,
FileSys::ContentRecordType::Program, title_id,
game_nca->GetBaseFile());
LOG_DEBUG(Service_AM, "Registered Program NCA");
} else {
LOG_WARNING(Service_AM, "Program NCA not found for title_id={:016X}", title_id);
}
// Register Control NCA
auto control_nca = system_provider.GetEntry(title_id, FileSys::ContentRecordType::Control);
if (control_nca) {
m_manual_provider.AddEntry(FileSys::TitleType::Application,
FileSys::ContentRecordType::Control, title_id,
control_nca->GetBaseFile());
LOG_DEBUG(Service_AM, "Registered Control NCA");
}
// Update the system's manual content provider slot to point to our populated provider
system_provider.SetSlot(FileSys::ContentProviderUnionSlot::FrontendManual,
&m_manual_provider);
}
// TODO: Read whether we need a preselected user from NACP?

View File

@@ -7,6 +7,7 @@
#include <functional>
#include <mutex>
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/am/am_types.h"
namespace Core {
@@ -63,6 +64,8 @@ private:
FrontendAppletParameters m_pending_parameters{};
std::unique_ptr<Process> m_pending_process{};
FileSys::ManualContentProvider m_manual_provider;
};
} // namespace Service::AM

View File

@@ -280,6 +280,9 @@ void WebBrowser::Initialize() {
case ShimKind::Lobby:
InitializeLobby();
break;
case ShimKind::Unknown8:
LOG_WARNING(Service_AM, "(STUBBED) called, Unknown8 Applet is not implemented");
break;
default:
ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind);
break;
@@ -317,6 +320,9 @@ void WebBrowser::Execute() {
case ShimKind::Lobby:
ExecuteLobby();
break;
case ShimKind::Unknown8:
WebBrowserExit(WebExitReason::EndButtonPressed);
break;
default:
ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind);
WebBrowserExit(WebExitReason::EndButtonPressed);

View File

@@ -30,6 +30,7 @@ enum class ShimKind : u32 {
Web = 5,
Wifi = 6,
Lobby = 7,
Unknown8 = 8,
};
enum class WebExitReason : u32 {

View File

@@ -29,7 +29,6 @@
#include "core/hle/service/filesystem/save_data_controller.h"
#include "core/hle/service/server_manager.h"
#include "core/loader/loader.h"
namespace Service::FileSystem {
static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
@@ -226,7 +225,8 @@ Result VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path_,
// Different parent directories - need to move by copying then deleting.
// Based on LibHac's approach: create dest, copy contents recursively, delete source.
LOG_DEBUG(Service_FS, "Moving directory across tree from \"{}\" to \"{}\"", src_path, dest_path);
LOG_DEBUG(Service_FS, "Moving directory across tree from \"{}\" to \"{}\"", src_path,
dest_path);
// Create the destination directory
auto dest_parent = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(dest_path));
@@ -429,7 +429,8 @@ std::shared_ptr<FileSys::SaveDataFactory> FileSystemController::CreateSaveDataFa
!Settings::values.global_custom_save_path.GetValue().empty()) {
base_save_path_str = Settings::values.global_custom_save_path.GetValue();
LOG_INFO(Service_FS, "Save Path: Using Global Custom Save Path as the base: {}", base_save_path_str);
LOG_INFO(Service_FS, "Save Path: Using Global Custom Save Path as the base: {}",
base_save_path_str);
} else {
base_save_path_str = Common::FS::GetCitronPathString(CitronPath::NANDDir);
LOG_INFO(Service_FS, "Save Path: Using default NAND as the base.");
@@ -440,10 +441,11 @@ std::shared_ptr<FileSys::SaveDataFactory> FileSystemController::CreateSaveDataFa
// 2. Check for Mirroring.
if (Settings::values.mirrored_save_paths.count(program_id)) {
LOG_INFO(Service_FS,
"Save Path: Mirroring detected for Program ID {:016X}. Syncing against the determined base directory.",
"Save Path: Mirroring detected for Program ID {:016X}. Syncing against the "
"determined base directory.",
program_id);
return std::make_shared<FileSys::SaveDataFactory>(system, program_id,
std::move(base_directory));
std::move(base_directory));
}
// 3. Check for Per-Game Custom Path override.
@@ -466,7 +468,6 @@ std::shared_ptr<FileSys::SaveDataFactory> FileSystemController::CreateSaveDataFa
LOG_INFO(Service_FS, "Save Path: No overrides found. Using the determined base directory.");
return std::make_shared<FileSys::SaveDataFactory>(system, program_id,
std::move(base_directory));
}
Result FileSystemController::OpenSDMC(FileSys::VirtualDir* out_sdmc) const {
@@ -616,7 +617,6 @@ FileSys::RegisteredCache* FileSystemController::GetSDMCContents() const {
return sdmc_factory->GetSDMCContents();
}
FileSys::PlaceholderCache* FileSystemController::GetSystemNANDPlaceholder() const {
LOG_TRACE(Service_FS, "Opening System NAND Placeholder");

View File

@@ -92,7 +92,6 @@ public:
FileSys::RegisteredCache* GetUserNANDContents() const;
FileSys::RegisteredCache* GetSDMCContents() const;
FileSys::RegisteredCache* GetGameCardContents() const;
FileSys::PlaceholderCache* GetSystemNANDPlaceholder() const;
FileSys::PlaceholderCache* GetUserNANDPlaceholder() const;
FileSys::PlaceholderCache* GetSDMCPlaceholder() const;
@@ -122,7 +121,9 @@ public:
void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
// getter for main.cpp to trigger the sync between custom game paths for separate emulators
FileSys::SaveDataFactory& GetSaveDataFactory() { return *global_save_data_factory; }
FileSys::SaveDataFactory& GetSaveDataFactory() {
return *global_save_data_factory;
}
void Reset();

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
@@ -12,14 +13,14 @@ IDaemonController::IDaemonController(Core::System& system_)
static const FunctionInfo functions[] = {
{0, D<&IDaemonController::GetAutoTransferEnabledForAccountAndApplication>, "GetAutoTransferEnabledForAccountAndApplication"},
{1, nullptr, "SetAutoTransferEnabledForAccountAndApplication"},
{2, nullptr, "GetGlobalUploadEnabledForAccount"},
{3, nullptr, "SetGlobalUploadEnabledForAccount"},
{2, D<&IDaemonController::GetGlobalUploadEnabledForAccount>, "GetGlobalUploadEnabledForAccount"},
{3, D<&IDaemonController::SetGlobalUploadEnabledForAccount>, "SetGlobalUploadEnabledForAccount"},
{4, nullptr, "TouchAccount"},
{5, nullptr, "GetGlobalDownloadEnabledForAccount"},
{6, nullptr, "SetGlobalDownloadEnabledForAccount"},
{5, D<&IDaemonController::GetGlobalDownloadEnabledForAccount>, "GetGlobalDownloadEnabledForAccount"},
{6, D<&IDaemonController::SetGlobalDownloadEnabledForAccount>, "SetGlobalDownloadEnabledForAccount"},
{10, nullptr, "GetForbiddenSaveDataIndication"},
{11, nullptr, "GetStopperObject"},
{12, nullptr, "GetState"},
{12, D<&IDaemonController::GetAutonomyTaskStatus>, "GetAutonomyTaskStatus"},
};
// clang-format on
@@ -37,4 +38,37 @@ Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<boo
R_SUCCEED();
}
Result IDaemonController::GetGlobalUploadEnabledForAccount(Out<bool> out_is_enabled,
Common::UUID user_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={}", user_id.FormattedString());
*out_is_enabled = false;
R_SUCCEED();
}
Result IDaemonController::SetGlobalUploadEnabledForAccount(bool is_enabled, Common::UUID user_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, is_enabled={} user_id={}", is_enabled,
user_id.FormattedString());
R_SUCCEED();
}
Result IDaemonController::GetGlobalDownloadEnabledForAccount(Out<bool> out_is_enabled,
Common::UUID user_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={}", user_id.FormattedString());
*out_is_enabled = false;
R_SUCCEED();
}
Result IDaemonController::SetGlobalDownloadEnabledForAccount(bool is_enabled,
Common::UUID user_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, is_enabled={} user_id={}", is_enabled,
user_id.FormattedString());
R_SUCCEED();
}
Result IDaemonController::GetAutonomyTaskStatus(Out<u8> out_status, Common::UUID user_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={}", user_id.FormattedString());
*out_status = 0; // Status: Idle
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/uuid.h"
@@ -15,6 +16,11 @@ public:
private:
Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
Common::UUID user_id, u64 application_id);
Result GetGlobalUploadEnabledForAccount(Out<bool> out_is_enabled, Common::UUID user_id);
Result SetGlobalUploadEnabledForAccount(bool is_enabled, Common::UUID user_id);
Result GetGlobalDownloadEnabledForAccount(Out<bool> out_is_enabled, Common::UUID user_id);
Result SetGlobalDownloadEnabledForAccount(bool is_enabled, Common::UUID user_id);
Result GetAutonomyTaskStatus(Out<u8> out_status, Common::UUID user_id);
};
} // namespace Service::OLSC

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
@@ -21,11 +22,11 @@ IRemoteStorageController::IRemoteStorageController(Core::System& system_)
{11, nullptr, "CreateDeleteDataTask"},
{12, nullptr, "DeleteSeriesInfo"},
{13, nullptr, "CreateRegisterNotificationTokenTask"},
{14, nullptr, "UpdateSeriesInfo"},
{14, D<&IRemoteStorageController::GetDataNewnessByApplicationId>, "GetDataNewnessByApplicationId"},
{15, nullptr, "RegisterUploadSaveDataTransferTaskForAutonomyRegistration"},
{16, nullptr, "CreateCleanupToDeleteSaveDataArchiveInfoTask"},
{17, nullptr, "ListDataInfo"},
{18, nullptr, "GetDataInfo"},
{18, D<&IRemoteStorageController::GetDataInfo>, "GetDataInfo"},
{19, nullptr, "Unknown19"},
{20, nullptr, "CreateSaveDataArchiveInfoCacheForSaveDataBackupUpdationTask"},
{21, nullptr, "ListSecondarySaves"},
@@ -33,6 +34,7 @@ IRemoteStorageController::IRemoteStorageController(Core::System& system_)
{23, nullptr, "TouchSecondarySave"},
{24, nullptr, "GetSecondarySaveDataInfo"},
{25, nullptr, "RegisterDownloadSaveDataTransferTaskForAutonomyRegistration"},
{27, D<&IRemoteStorageController::GetDataInfo>, "GetDataInfoV2"}, // [20.0.0+]
{28, D<&IRemoteStorageController::Unknown28>, "Unknown28"}, // [20.2.0+]
{900, nullptr, "Unknown900"},
{901, D<&IRemoteStorageController::Unknown901>, "Unknown901"}, // [20.2.0+]
@@ -44,6 +46,20 @@ IRemoteStorageController::IRemoteStorageController(Core::System& system_)
IRemoteStorageController::~IRemoteStorageController() = default;
Result IRemoteStorageController::GetDataNewnessByApplicationId(Out<u8> out_newness,
u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id);
*out_newness = 0;
R_SUCCEED();
}
Result IRemoteStorageController::GetDataInfo(Out<std::array<u8, 0x38>> out_data,
u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, application_id={:016X}", application_id);
out_data->fill(0);
R_SUCCEED();
}
Result IRemoteStorageController::GetSecondarySave(Out<bool> out_has_secondary_save,
Out<std::array<u64, 3>> out_unknown,
u64 application_id) {

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
@@ -12,9 +13,11 @@ public:
~IRemoteStorageController() override;
private:
Result GetDataNewnessByApplicationId(Out<u8> out_newness, u64 application_id);
Result GetDataInfo(Out<std::array<u8, 0x38>> out_data, u64 application_id);
Result GetSecondarySave(Out<bool> out_has_secondary_save, Out<std::array<u64, 3>> out_unknown,
u64 application_id);
Result Unknown28(); // [20.2.0+]
Result Unknown28(); // [20.2.0+]
Result Unknown901(); // [20.2.0+]
};

View File

@@ -1,8 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_serialization.h"
#include "core/hle/service/olsc/native_handle_holder.h"
#include "core/hle/service/olsc/remote_storage_controller.h"
#include "core/hle/service/olsc/transfer_task_list_controller.h"
namespace Service::OLSC {
@@ -19,7 +21,7 @@ ITransferTaskListController::ITransferTaskListController(Core::System& system_)
{5, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder"},
{6, nullptr, "Unknown6"},
{7, nullptr, "Unknown7"},
{8, nullptr, "GetRemoteStorageController"},
{8, D<&ITransferTaskListController::GetRemoteStorageController>, "GetRemoteStorageController"},
{9, D<&ITransferTaskListController::GetNativeHandleHolder>, "GetNativeHandleHolder2"},
{10, nullptr, "Unknown10"},
{11, nullptr, "Unknown11"},
@@ -31,12 +33,12 @@ ITransferTaskListController::ITransferTaskListController(Core::System& system_)
{17, nullptr, "Unknown17"},
{18, nullptr, "Unknown18"},
{19, nullptr, "Unknown19"},
{20, nullptr, "Unknown20"},
{20, D<&ITransferTaskListController::Unknown20>, "Unknown20"},
{21, nullptr, "Unknown21"},
{22, nullptr, "Unknown22"},
{23, nullptr, "Unknown23"},
{24, nullptr, "Unknown24"},
{25, nullptr, "Unknown25"},
{24, D<&ITransferTaskListController::GetCurrentTransferTaskInfo>, "GetCurrentTransferTaskInfo"},
{25, D<&ITransferTaskListController::FindTransferTaskInfo>, "FindTransferTaskInfo"},
};
// clang-format on
@@ -52,4 +54,30 @@ Result ITransferTaskListController::GetNativeHandleHolder(
R_SUCCEED();
}
Result ITransferTaskListController::GetRemoteStorageController(
Out<SharedPointer<IRemoteStorageController>> out_controller) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_controller = std::make_shared<IRemoteStorageController>(system);
R_SUCCEED();
}
Result ITransferTaskListController::Unknown20() {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
R_SUCCEED();
}
Result ITransferTaskListController::GetCurrentTransferTaskInfo(Out<std::array<u8, 0x30>> out_info,
u8 unknown) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, unknown={:#x}", unknown);
out_info->fill(0);
R_SUCCEED();
}
Result ITransferTaskListController::FindTransferTaskInfo(Out<std::array<u8, 0x30>> out_info,
InBuffer<BufferAttr_HipcAutoSelect> in) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, in_size={}", in.size());
out_info->fill(0);
R_SUCCEED();
}
} // namespace Service::OLSC

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/cmif_types.h"
@@ -7,6 +8,7 @@
namespace Service::OLSC {
class INativeHandleHolder;
class IRemoteStorageController;
class ITransferTaskListController final : public ServiceFramework<ITransferTaskListController> {
public:
@@ -15,6 +17,11 @@ public:
private:
Result GetNativeHandleHolder(Out<SharedPointer<INativeHandleHolder>> out_holder);
Result GetRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_controller);
Result Unknown20();
Result GetCurrentTransferTaskInfo(Out<std::array<u8, 0x30>> out_info, u8 unknown);
Result FindTransferTaskInfo(Out<std::array<u8, 0x30>> out_info,
InBuffer<BufferAttr_HipcAutoSelect> in);
};
} // namespace Service::OLSC