forked from eden-emu/eden
[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:
parent
3e8fe622a7
commit
de46b8e817
13 changed files with 221 additions and 79 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue