[fs, qlaunch] add CreateSaveDataFileSystemWithCreationInfo2 and make qlaunch work again (#2760)

Fixes qlaunch regression I introduced previously. Add a few known structs.
Adds CreateSaveDataFileSystemWithCreationInfo2, which is called when games are started via qlaunch and corrupts save files.

Reviewed-on: eden-emu/eden#2760
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: unknown <sahyno1996@gmail.com>
Co-committed-by: unknown <sahyno1996@gmail.com>
This commit is contained in:
unknown 2025-10-17 22:23:21 +02:00 committed by crueter
parent 3e8fe622a7
commit de46b8e817
Signed by untrusted user: crueter
GPG key ID: 425ACD2D4830EBC6
13 changed files with 221 additions and 79 deletions

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -68,6 +71,11 @@ enum class SaveDataMetaType : u8 {
ExtensionContext = 2,
};
enum class SaveDataFormatType : u8 {
Normal = 0,
NoJournal = 1,
};
struct SaveDataMetaInfo {
u32 size;
SaveDataMetaType type;
@ -185,4 +193,31 @@ struct HashSalt {
static_assert(std::is_trivially_copyable_v<HashSalt>, "Data type must be trivially copyable.");
static_assert(sizeof(HashSalt) == HashSalt::Size);
struct SaveDataCreationInfo2 {
static constexpr u32 SaveDataCreationInfo2Version = 0x00010000;
u32 version;
SaveDataAttribute attribute;
s64 size;
s64 journal_size;
s64 block_size;
u64 owner_id;
u32 flags;
SaveDataSpaceId space_id;
SaveDataFormatType format_type;
bool pseudo;
u8 reserved1;
bool is_hash_salt_enabled;
u8 reserved2;
HashSalt hash_salt;
SaveDataMetaType meta_type;
u8 reserved3;
s32 meta_size;
u8 reserved4;
};
static_assert(std::is_trivially_copyable_v<SaveDataCreationInfo2>,
"Data type must be trivially copyable.");
static_assert(sizeof(SaveDataCreationInfo2) == 0xA0, "SaveDataCreationInfo has invalid size.");
} // namespace FileSys

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -76,6 +79,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{34, D<&FSP_SRV::GetCacheStorageSize>, "GetCacheStorageSize"},
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
{36, nullptr, "OpenHostFileSystemWithOption"},
{37, D<&FSP_SRV::CreateSaveDataFileSystemWithCreationInfo2>, "CreateSaveDataFileSystemWithCreationInfo2"},
{51, D<&FSP_SRV::OpenSaveDataFileSystem>, "OpenSaveDataFileSystem"},
{52, D<&FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId>, "OpenSaveDataFileSystemBySystemSaveDataId"},
{53, D<&FSP_SRV::OpenReadOnlySaveDataFileSystem>, "OpenReadOnlySaveDataFileSystem"},
@ -244,6 +248,13 @@ Result FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(
save_struct));
}
Result FSP_SRV::CreateSaveDataFileSystemWithCreationInfo2(
FileSys::SaveDataCreationInfo2 save_data_creation_info) {
FileSys::VirtualDir save_data_dir{};
R_RETURN(save_data_controller->CreateSaveData(&save_data_dir, save_data_creation_info.space_id,
save_data_creation_info.attribute));
}
Result FSP_SRV::IsExFatSupported(Out<bool> out_is_supported) {
LOG_WARNING(Service_FS, "(STUBBED) called");

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -55,6 +58,8 @@ private:
FileSys::SaveDataAttribute save_struct, u128 uid);
Result CreateSaveDataFileSystemBySystemSaveDataId(
FileSys::SaveDataAttribute save_struct, FileSys::SaveDataCreationInfo save_create_struct);
Result CreateSaveDataFileSystemWithCreationInfo2(
FileSys::SaveDataCreationInfo2 save_data_creation_info);
Result IsExFatSupported(Out<bool> out_is_supported);
Result OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface,
FileSys::SaveDataSpaceId space_id,

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

View file

@ -206,12 +206,12 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{1600, nullptr, "GetSystemSeedForPseudoDeviceId"},
{1601, nullptr, "ResetSystemSeedForPseudoDeviceId"},
{1700, nullptr, "ListApplicationDownloadingContentMeta"},
{1701, D<&IApplicationManagerInterface::GetApplicationView>, "GetApplicationView"},
{1701, D<&IApplicationManagerInterface::GetApplicationViewDeprecated>, "GetApplicationViewDeprecated"},
{1702, nullptr, "GetApplicationDownloadTaskStatus"},
{1703, nullptr, "GetApplicationViewDownloadErrorContext"},
{1704, D<&IApplicationManagerInterface::GetApplicationViewWithPromotionInfo>, "GetApplicationViewWithPromotionInfo"},
{1705, nullptr, "IsPatchAutoDeletableApplication"},
{1706, D<&IApplicationManagerInterface::Unknown1706>, "Unknown1706"},
{1706, D<&IApplicationManagerInterface::GetApplicationView>, "GetApplicationView"},
{1800, nullptr, "IsNotificationSetupCompleted"},
{1801, nullptr, "GetLastNotificationInfoCount"},
{1802, nullptr, "ListLastNotificationInfo"},
@ -329,7 +329,7 @@ Result IApplicationManagerInterface::GetApplicationControlData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) {
LOG_DEBUG(Service_NS, "called");
R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationControlData(
R_RETURN(IReadOnlyApplicationControlDataInterface(system).GetApplicationControlDataOld(
out_buffer, out_actual_size, application_control_source, application_id));
}
@ -410,7 +410,7 @@ Result IApplicationManagerInterface::IsAnyApplicationEntityInstalled(
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationView(
Result IApplicationManagerInterface::GetApplicationViewDeprecated(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids) {
const auto size = (std::min)(out_application_views.size(), application_ids.size());
@ -419,7 +419,7 @@ Result IApplicationManagerInterface::GetApplicationView(
for (size_t i = 0; i < size; i++) {
ApplicationView view{};
view.application_id = application_ids[i];
view.unk = 0x70000;
view.version = 0x70000;
view.flags = 0x401f17;
out_application_views[i] = view;
@ -437,7 +437,7 @@ Result IApplicationManagerInterface::GetApplicationViewWithPromotionInfo(
for (size_t i = 0; i < size; i++) {
ApplicationViewWithPromotionInfo view{};
view.view.application_id = application_ids[i];
view.view.unk = 0x70000;
view.view.version = 0x70000;
view.view.flags = 0x401f17;
view.promotion = {};
@ -447,6 +447,24 @@ Result IApplicationManagerInterface::GetApplicationViewWithPromotionInfo(
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationView(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids) {
const auto size = (std::min)(out_application_views.size(), application_ids.size());
LOG_WARNING(Service_NS, "(STUBBED) called, size={}", application_ids.size());
for (size_t i = 0; i < size; i++) {
ApplicationView view{};
view.application_id = application_ids[i];
view.version = 0x70000;
view.flags = 0x401f17;
out_application_views[i] = view;
}
R_SUCCEED();
}
Result IApplicationManagerInterface::GetApplicationRightsOnClient(
OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count,
u32 flags, u64 application_id, Uid account_id) {
@ -535,31 +553,6 @@ Result IApplicationManagerInterface::RequestDownloadApplicationControlDataInBack
R_SUCCEED();
}
Result IApplicationManagerInterface::Unknown1706(
OutBuffer<BufferAttr_HipcAutoSelect> out_buffer_58,
InBuffer<BufferAttr_HipcMapAlias> in_buffer_8) {
LOG_WARNING(Service_NS, "(STUBBED) Unknown1706 called: out_size={} in_size={}",
out_buffer_58.size(), in_buffer_8.size());
if (out_buffer_58.size() < 0x58 || in_buffer_8.size() < 0x8) {
R_THROW(ResultUnknown);
}
u64 application_id = 0;
std::memcpy(&application_id, in_buffer_8.data(), sizeof(u64));
ApplicationView view{};
view.application_id = application_id;
view.unk = 0x70000;
view.flags = 0x401f17;
std::memset(out_buffer_58.data(), 0, out_buffer_58.size());
std::memcpy(out_buffer_58.data(), &view, sizeof(ApplicationView));
R_SUCCEED();
}
Result IApplicationManagerInterface::Unknown4022(
OutCopyHandle<Kernel::KReadableEvent> out_event) {
LOG_WARNING(Service_NS, "(STUBBED) called");

View file

@ -33,12 +33,15 @@ public:
Result GetApplicationRecordUpdateSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result GetGameCardMountFailureEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
Result IsAnyApplicationEntityInstalled(Out<bool> out_is_any_application_entity_installed);
Result GetApplicationView(
Result GetApplicationViewDeprecated(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids);
Result GetApplicationViewWithPromotionInfo(
OutArray<ApplicationViewWithPromotionInfo, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids);
Result GetApplicationView(
OutArray<ApplicationView, BufferAttr_HipcMapAlias> out_application_views,
InArray<u64, BufferAttr_HipcMapAlias> application_ids);
Result GetApplicationRightsOnClient(
OutArray<ApplicationRightsOnClient, BufferAttr_HipcMapAlias> out_rights, Out<u32> out_count,
u32 flags, u64 application_id, Uid account_id);
@ -59,8 +62,6 @@ public:
Result RequestDownloadApplicationControlDataInBackground(u64 unk,
u64 application_id);
Result Unknown1706(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer_58,
InBuffer<BufferAttr_HipcMapAlias> in_buffer_8);
private:
KernelHelpers::ServiceContext service_context;

View file

@ -42,20 +42,26 @@ struct ApplicationRecord {
};
static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord has incorrect size.");
/// ApplicationDownloadState
struct ApplicationDownloadState {
u64 downloaded_size;
u64 total_size;
u32 unk_x10;
u8 state;
u8 unk_x19;
std::array<u8, 0x2> unk_x1a;
u64 unk_x20;
};
static_assert(sizeof(ApplicationDownloadState) == 0x20,
"ApplicationDownloadState has incorrect size.");
/// ApplicationView
struct ApplicationView {
u64 application_id; ///< ApplicationId.
u32 unk; ///< Unknown.
u32 flags; ///< Flags.
std::array<u8, 0x10> unk_x10; ///< Unknown.
u32 unk_x20; ///< Unknown.
u16 unk_x24; ///< Unknown.
std::array<u8, 0x2> unk_x26; ///< Unknown.
std::array<u8, 0x8> unk_x28; ///< Unknown.
std::array<u8, 0x10> unk_x30; ///< Unknown.
u32 unk_x40; ///< Unknown.
u8 unk_x44; ///< Unknown.
std::array<u8, 0xb> unk_x45; ///< Unknown.
u64 application_id; ///< ApplicationId.
u32 version; ///< Application Version(?)
u32 flags; ///< Flags.
ApplicationDownloadState download_state; ///< \ref ApplicationDownloadState
ApplicationDownloadState download_progress; ///< \ref ApplicationDownloadState
};
static_assert(sizeof(ApplicationView) == 0x50, "ApplicationView has incorrect size.");
@ -82,13 +88,13 @@ struct PromotionInfo {
};
static_assert(sizeof(PromotionInfo) == 0x20, "PromotionInfo has incorrect size.");
// TODO(Maufeat): NsApplicationViewWithPromotionInfo is on SDK20+ 0x78 bytes
/// NsApplicationViewWithPromotionInfo
struct ApplicationViewWithPromotionInfo {
ApplicationView view; ///< \ref NsApplicationView
PromotionInfo promotion; ///< \ref NsPromotionInfo
std::array<u8, 0x8> padding{}; ///< Extra padding for newer HOS versions
};
static_assert(sizeof(ApplicationViewWithPromotionInfo) == 0x78,
static_assert(sizeof(ApplicationViewWithPromotionInfo) == 0x70,
"ApplicationViewWithPromotionInfo has incorrect size.");
struct ApplicationOccupiedSizeEntity {

View file

@ -22,12 +22,12 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
: ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlData>, "GetApplicationControlData"},
{0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataOld>, "GetApplicationControlDataOld"},
{1, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"},
{2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{4, nullptr, "SelectApplicationDesiredLanguage"},
{5, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDisplayData>, "GetApplicationDisplayData"},
{5, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithIconSize>, "GetApplicationControlDataWithIconSize"},
};
// clang-format on
@ -36,7 +36,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlDataOld(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
@ -124,32 +124,87 @@ Result IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLan
R_SUCCEED();
}
Result IReadOnlyApplicationControlDataInterface::GetApplicationDisplayData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u64> out_size, u64 language_code,
u64 application_id) {
LOG_INFO(Service_NS, "called with application_id={:016X}, language_code={:016X}",
application_id, language_code);
constexpr u64 payload_size = sizeof(ApplicationDisplayData);
if (out_buffer.size() < payload_size) {
LOG_ERROR(Service_NS, "output buffer is too small! (actual={}, expected_min={})",
out_buffer.size(), payload_size);
R_THROW(ResultUnknown);
}
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size,
ApplicationControlSource application_control_source, u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
application_control_source, application_id);
const FileSys::PatchManager pm{application_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
const auto size = out_buffer.size();
ApplicationDisplayData display_data{};
const auto icon_size = control.second ? control.second->GetSize() : 0;
const auto total_size = sizeof(FileSys::RawNACP) + icon_size;
std::memset(display_data.application_name.data(), 0, display_data.application_name.size());
std::memset(display_data.developer_name.data(), 0, display_data.developer_name.size());
if (size < total_size) {
LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)",
size);
R_THROW(ResultUnknown);
}
std::memcpy(out_buffer.data(), &display_data, payload_size);
*out_size = payload_size;
if (control.first != nullptr) {
const auto bytes = control.first->GetRawBytes();
std::memcpy(out_buffer.data(), bytes.data(), bytes.size());
} else {
LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero",
application_id);
std::memset(out_buffer.data(), 0, sizeof(FileSys::RawNACP));
}
if (control.second != nullptr) {
control.second->Read(out_buffer.data() + sizeof(FileSys::RawNACP), icon_size);
} else {
LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id);
}
*out_actual_size = static_cast<u32>(total_size);
R_SUCCEED();
}
Result IReadOnlyApplicationControlDataInterface::GetApplicationControlDataWithIconSize(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u64> out_total_size,
ApplicationControlSource application_control_source,
u64 application_id) {
LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}",
application_control_source, application_id);
constexpr size_t kExpectedBufferSize = 0x14000;
constexpr size_t kNACPSize = sizeof(FileSys::RawNACP);
constexpr size_t kMaxIconSize = kExpectedBufferSize - kNACPSize;
const FileSys::PatchManager pm{application_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
const auto size = out_buffer.size();
if (size < kExpectedBufferSize) {
LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, required={:016X})", size, kExpectedBufferSize);
R_THROW(ResultUnknown);
}
// Copy NACP
if (control.first != nullptr) {
const auto bytes = control.first->GetRawBytes();
std::memcpy(out_buffer.data(), bytes.data(), bytes.size());
} else {
std::memset(out_buffer.data(), 0, kNACPSize);
}
// Copy icon, pad with zeros if needed
size_t icon_size = control.second ? control.second->GetSize() : 0;
if (icon_size > kMaxIconSize) {
icon_size = kMaxIconSize; // Truncate if too large
}
if (control.second != nullptr && icon_size > 0) {
control.second->Read(out_buffer.data() + kNACPSize, icon_size);
} else {
std::memset(out_buffer.data() + kNACPSize, 0, kMaxIconSize);
}
*out_total_size = kExpectedBufferSize;
R_SUCCEED();
}

View file

@ -19,7 +19,7 @@ public:
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
~IReadOnlyApplicationControlDataInterface() override;
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Result GetApplicationControlDataOld(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u32> out_actual_size,
ApplicationControlSource application_control_source,
u64 application_id);
@ -27,10 +27,15 @@ public:
u32 supported_languages);
Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code,
ApplicationLanguage application_language);
Result GetApplicationDisplayData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u64> out_size, u64 language_code,
u64 application_id);
Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u32> out_actual_size,
ApplicationControlSource application_control_source,
u64 application_id);
Result GetApplicationControlDataWithIconSize(
OutBuffer<BufferAttr_HipcMapAlias> out_buffer,
Out<u64> out_total_size,
ApplicationControlSource application_control_source,
u64 application_id);
};
} // namespace Service::NS

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -19,7 +22,7 @@ IDaemonController::IDaemonController(Core::System& system_)
{6, nullptr, "SetGlobalDownloadEnabledForAccount"},
{10, nullptr, "GetForbiddenSaveDataIndication"},
{11, nullptr, "GetStopperObject"},
{12, nullptr, "GetState"},
{12, D<&IDaemonController::GetState>, "GetState"},
};
// clang-format on
@ -37,4 +40,11 @@ Result IDaemonController::GetAutoTransferEnabledForAccountAndApplication(Out<boo
R_SUCCEED();
}
Result IDaemonController::GetState(Out<u8> state, Common::UUID user_id, u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called, user_id={} application_id={:016X}",
user_id.FormattedString(), application_id);
*state = 0;
R_SUCCEED();
}
} // namespace Service::OLSC

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -15,6 +18,7 @@ public:
private:
Result GetAutoTransferEnabledForAccountAndApplication(Out<bool> out_is_enabled,
Common::UUID user_id, u64 application_id);
Result GetState(Out<u8> state, Common::UUID user_id, u64 application_id);
};
} // namespace Service::OLSC

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -100,10 +103,13 @@ Result IOlscServiceForSystemService::OpenDaemonController(
R_SUCCEED();
}
Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(Out<u16> out_policy_info,
u64 application_id) {
Result IOlscServiceForSystemService::GetDataTransferPolicyInfo(
Out<DataTransferPolicy> out_policy_info, u64 application_id) {
LOG_WARNING(Service_OLSC, "(STUBBED) called");
*out_policy_info = 0;
DataTransferPolicy policy{};
policy.upload_policy = 0;
policy.download_policy = 0;
*out_policy_info = policy;
R_SUCCEED();
}

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@ -10,6 +13,11 @@ class IDaemonController;
class IRemoteStorageController;
class ITransferTaskListController;
struct DataTransferPolicy {
u8 upload_policy;
u8 download_policy;
};
class IOlscServiceForSystemService final : public ServiceFramework<IOlscServiceForSystemService> {
public:
explicit IOlscServiceForSystemService(Core::System& system_);
@ -20,7 +28,7 @@ private:
Out<SharedPointer<ITransferTaskListController>> out_interface);
Result OpenRemoteStorageController(Out<SharedPointer<IRemoteStorageController>> out_interface);
Result OpenDaemonController(Out<SharedPointer<IDaemonController>> out_interface);
Result GetDataTransferPolicyInfo(Out<u16> out_policy_info, u64 application_id);
Result GetDataTransferPolicyInfo(Out<DataTransferPolicy> out_policy_info, u64 application_id);
Result CloneService(Out<SharedPointer<IOlscServiceForSystemService>> out_interface);
};