From 7c2e9a6596c8b6c5d366c3eaaf926ad7db406486 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Thu, 8 Feb 2024 16:58:44 -0600 Subject: service: bcat: Migrate and refractor service to new IPC --- src/core/CMakeLists.txt | 17 +- src/core/hle/service/bcat/backend/backend.cpp | 30 +- src/core/hle/service/bcat/backend/backend.h | 54 +- src/core/hle/service/bcat/bcat.cpp | 30 +- src/core/hle/service/bcat/bcat.h | 9 +- src/core/hle/service/bcat/bcat_interface.cpp | 61 +++ src/core/hle/service/bcat/bcat_interface.h | 40 ++ src/core/hle/service/bcat/bcat_module.cpp | 606 --------------------- src/core/hle/service/bcat/bcat_module.h | 46 -- src/core/hle/service/bcat/bcat_result.h | 20 + src/core/hle/service/bcat/bcat_service.cpp | 131 +++++ src/core/hle/service/bcat/bcat_service.h | 45 ++ src/core/hle/service/bcat/bcat_types.h | 60 ++ src/core/hle/service/bcat/bcat_util.h | 39 ++ .../bcat/delivery_cache_directory_service.cpp | 81 +++ .../bcat/delivery_cache_directory_service.h | 33 ++ .../service/bcat/delivery_cache_file_service.cpp | 81 +++ .../hle/service/bcat/delivery_cache_file_service.h | 33 ++ .../bcat/delivery_cache_progress_service.cpp | 41 ++ .../service/bcat/delivery_cache_progress_service.h | 35 ++ .../bcat/delivery_cache_storage_service.cpp | 57 ++ .../service/bcat/delivery_cache_storage_service.h | 36 ++ 22 files changed, 850 insertions(+), 735 deletions(-) create mode 100644 src/core/hle/service/bcat/bcat_interface.cpp create mode 100644 src/core/hle/service/bcat/bcat_interface.h delete mode 100644 src/core/hle/service/bcat/bcat_module.cpp delete mode 100644 src/core/hle/service/bcat/bcat_module.h create mode 100644 src/core/hle/service/bcat/bcat_result.h create mode 100644 src/core/hle/service/bcat/bcat_service.cpp create mode 100644 src/core/hle/service/bcat/bcat_service.h create mode 100644 src/core/hle/service/bcat/bcat_types.h create mode 100644 src/core/hle/service/bcat/bcat_util.h create mode 100644 src/core/hle/service/bcat/delivery_cache_directory_service.cpp create mode 100644 src/core/hle/service/bcat/delivery_cache_directory_service.h create mode 100644 src/core/hle/service/bcat/delivery_cache_file_service.cpp create mode 100644 src/core/hle/service/bcat/delivery_cache_file_service.h create mode 100644 src/core/hle/service/bcat/delivery_cache_progress_service.cpp create mode 100644 src/core/hle/service/bcat/delivery_cache_progress_service.h create mode 100644 src/core/hle/service/bcat/delivery_cache_storage_service.cpp create mode 100644 src/core/hle/service/bcat/delivery_cache_storage_service.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index eb8f643a2..703e6050f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -514,8 +514,21 @@ add_library(core STATIC hle/service/bcat/backend/backend.h hle/service/bcat/bcat.cpp hle/service/bcat/bcat.h - hle/service/bcat/bcat_module.cpp - hle/service/bcat/bcat_module.h + hle/service/bcat/bcat_interface.cpp + hle/service/bcat/bcat_interface.h + hle/service/bcat/bcat_result.h + hle/service/bcat/bcat_service.cpp + hle/service/bcat/bcat_service.h + hle/service/bcat/bcat_types.h + hle/service/bcat/bcat_util.h + hle/service/bcat/delivery_cache_directory_service.cpp + hle/service/bcat/delivery_cache_directory_service.h + hle/service/bcat/delivery_cache_file_service.cpp + hle/service/bcat/delivery_cache_file_service.h + hle/service/bcat/delivery_cache_progress_service.cpp + hle/service/bcat/delivery_cache_progress_service.h + hle/service/bcat/delivery_cache_storage_service.cpp + hle/service/bcat/delivery_cache_storage_service.h hle/service/bpc/bpc.cpp hle/service/bpc/bpc.h hle/service/btdrv/btdrv.cpp diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index 847f76987..1993493a9 100644 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp @@ -33,18 +33,18 @@ void ProgressServiceBackend::SetTotalSize(u64 size) { } void ProgressServiceBackend::StartConnecting() { - impl.status = DeliveryCacheProgressImpl::Status::Connecting; + impl.status = DeliveryCacheProgressStatus::Connecting; SignalUpdate(); } void ProgressServiceBackend::StartProcessingDataList() { - impl.status = DeliveryCacheProgressImpl::Status::ProcessingDataList; + impl.status = DeliveryCacheProgressStatus::ProcessingDataList; SignalUpdate(); } void ProgressServiceBackend::StartDownloadingFile(std::string_view dir_name, std::string_view file_name, u64 file_size) { - impl.status = DeliveryCacheProgressImpl::Status::Downloading; + impl.status = DeliveryCacheProgressStatus::Downloading; impl.current_downloaded_bytes = 0; impl.current_total_bytes = file_size; std::memcpy(impl.current_directory.data(), dir_name.data(), @@ -65,7 +65,7 @@ void ProgressServiceBackend::FinishDownloadingFile() { } void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) { - impl.status = DeliveryCacheProgressImpl::Status::Committing; + impl.status = DeliveryCacheProgressStatus::Committing; impl.current_file.fill(0); impl.current_downloaded_bytes = 0; impl.current_total_bytes = 0; @@ -76,7 +76,7 @@ void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) { void ProgressServiceBackend::FinishDownload(Result result) { impl.total_downloaded_bytes = impl.total_bytes; - impl.status = DeliveryCacheProgressImpl::Status::Done; + impl.status = DeliveryCacheProgressStatus::Done; impl.result = result; SignalUpdate(); } @@ -85,15 +85,15 @@ void ProgressServiceBackend::SignalUpdate() { update_event->Signal(); } -Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} +BcatBackend::BcatBackend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} -Backend::~Backend() = default; +BcatBackend::~BcatBackend() = default; -NullBackend::NullBackend(DirectoryGetter getter) : Backend(std::move(getter)) {} +NullBcatBackend::NullBcatBackend(DirectoryGetter getter) : BcatBackend(std::move(getter)) {} -NullBackend::~NullBackend() = default; +NullBcatBackend::~NullBcatBackend() = default; -bool NullBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) { +bool NullBcatBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, title.build_id); @@ -101,8 +101,8 @@ bool NullBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& prog return true; } -bool NullBackend::SynchronizeDirectory(TitleIDVersion title, std::string name, - ProgressServiceBackend& progress) { +bool NullBcatBackend::SynchronizeDirectory(TitleIDVersion title, std::string name, + ProgressServiceBackend& progress) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}, name={}", title.title_id, title.build_id, name); @@ -110,18 +110,18 @@ bool NullBackend::SynchronizeDirectory(TitleIDVersion title, std::string name, return true; } -bool NullBackend::Clear(u64 title_id) { +bool NullBcatBackend::Clear(u64 title_id) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); return true; } -void NullBackend::SetPassphrase(u64 title_id, const Passphrase& passphrase) { +void NullBcatBackend::SetPassphrase(u64 title_id, const Passphrase& passphrase) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, Common::HexToString(passphrase)); } -std::optional> NullBackend::GetLaunchParameter(TitleIDVersion title) { +std::optional> NullBcatBackend::GetLaunchParameter(TitleIDVersion title) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, title.build_id); return std::nullopt; diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index aa36d29d5..3680f6c9c 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h @@ -10,6 +10,7 @@ #include "common/common_types.h" #include "core/file_sys/vfs/vfs_types.h" #include "core/hle/result.h" +#include "core/hle/service/bcat/bcat_types.h" #include "core/hle/service/kernel_helpers.h" namespace Core { @@ -24,44 +25,6 @@ class KReadableEvent; namespace Service::BCAT { -struct DeliveryCacheProgressImpl; - -using DirectoryGetter = std::function; -using Passphrase = std::array; - -struct TitleIDVersion { - u64 title_id; - u64 build_id; -}; - -using DirectoryName = std::array; -using FileName = std::array; - -struct DeliveryCacheProgressImpl { - enum class Status : s32 { - None = 0x0, - Queued = 0x1, - Connecting = 0x2, - ProcessingDataList = 0x3, - Downloading = 0x4, - Committing = 0x5, - Done = 0x9, - }; - - Status status; - Result result = ResultSuccess; - DirectoryName current_directory; - FileName current_file; - s64 current_downloaded_bytes; ///< Bytes downloaded on current file. - s64 current_total_bytes; ///< Bytes total on current file. - s64 total_downloaded_bytes; ///< Bytes downloaded on overall download. - s64 total_bytes; ///< Bytes total on overall download. - INSERT_PADDING_BYTES( - 0x198); ///< Appears to be unused in official code, possibly reserved for future use. -}; -static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200, - "DeliveryCacheProgressImpl has incorrect size."); - // A class to manage the signalling to the game about BCAT download progress. // Some of this class is implemented in module.cpp to avoid exposing the implementation structure. class ProgressServiceBackend { @@ -107,10 +70,10 @@ private: }; // A class representing an abstract backend for BCAT functionality. -class Backend { +class BcatBackend { public: - explicit Backend(DirectoryGetter getter); - virtual ~Backend(); + explicit BcatBackend(DirectoryGetter getter); + virtual ~BcatBackend(); // Called when the backend is needed to synchronize the data for the game with title ID and // version in title. A ProgressServiceBackend object is provided to alert the application of @@ -135,10 +98,10 @@ protected: }; // A backend of BCAT that provides no operation. -class NullBackend : public Backend { +class NullBcatBackend : public BcatBackend { public: - explicit NullBackend(DirectoryGetter getter); - ~NullBackend() override; + explicit NullBcatBackend(DirectoryGetter getter); + ~NullBcatBackend() override; bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override; bool SynchronizeDirectory(TitleIDVersion title, std::string name, @@ -151,6 +114,7 @@ public: std::optional> GetLaunchParameter(TitleIDVersion title) override; }; -std::unique_ptr CreateBackendFromSettings(Core::System& system, DirectoryGetter getter); +std::unique_ptr CreateBackendFromSettings(Core::System& system, + DirectoryGetter getter); } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat.cpp b/src/core/hle/service/bcat/bcat.cpp index d0ac17324..31e9d8662 100644 --- a/src/core/hle/service/bcat/bcat.cpp +++ b/src/core/hle/service/bcat/bcat.cpp @@ -1,24 +1,26 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/hle/service/bcat/backend/backend.h" #include "core/hle/service/bcat/bcat.h" +#include "core/hle/service/bcat/bcat_interface.h" +#include "core/hle/service/server_manager.h" namespace Service::BCAT { -BCAT::BCAT(Core::System& system_, std::shared_ptr module_, - FileSystem::FileSystemController& fsc_, const char* name_) - : Interface(system_, std::move(module_), fsc_, name_) { - // clang-format off - static const FunctionInfo functions[] = { - {0, &BCAT::CreateBcatService, "CreateBcatService"}, - {1, &BCAT::CreateDeliveryCacheStorageService, "CreateDeliveryCacheStorageService"}, - {2, &BCAT::CreateDeliveryCacheStorageServiceWithApplicationId, "CreateDeliveryCacheStorageServiceWithApplicationId"}, - {3, nullptr, "CreateDeliveryCacheProgressService"}, - {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"}, - }; - // clang-format on - RegisterHandlers(functions); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("bcat:a", + std::make_shared(system, "bcat:a")); + server_manager->RegisterNamedService("bcat:m", + std::make_shared(system, "bcat:m")); + server_manager->RegisterNamedService("bcat:u", + std::make_shared(system, "bcat:u")); + server_manager->RegisterNamedService("bcat:s", + std::make_shared(system, "bcat:s")); + + ServerManager::RunServer(std::move(server_manager)); } -BCAT::~BCAT() = default; } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat.h b/src/core/hle/service/bcat/bcat.h index db9d3c8c5..2aaffc693 100644 --- a/src/core/hle/service/bcat/bcat.h +++ b/src/core/hle/service/bcat/bcat.h @@ -3,7 +3,7 @@ #pragma once -#include "core/hle/service/bcat/bcat_module.h" +#include "core/hle/service/service.h" namespace Core { class System; @@ -11,11 +11,6 @@ class System; namespace Service::BCAT { -class BCAT final : public Module::Interface { -public: - explicit BCAT(Core::System& system_, std::shared_ptr module_, - FileSystem::FileSystemController& fsc_, const char* name_); - ~BCAT() override; -}; +void LoopProcess(Core::System& system); } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_interface.cpp b/src/core/hle/service/bcat/bcat_interface.cpp new file mode 100644 index 000000000..2d9a0efcc --- /dev/null +++ b/src/core/hle/service/bcat/bcat_interface.cpp @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/bcat/bcat_interface.h" +#include "core/hle/service/bcat/bcat_service.h" +#include "core/hle/service/bcat/delivery_cache_storage_service.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/filesystem/filesystem.h" + +namespace Service::BCAT { + +std::unique_ptr CreateBackendFromSettings([[maybe_unused]] Core::System& system, + DirectoryGetter getter) { + return std::make_unique(std::move(getter)); +} + +BcatInterface::BcatInterface(Core::System& system_, const char* name_) + : ServiceFramework{system_, name_}, fsc{system.GetFileSystemController()} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&BcatInterface::CreateBcatService>, "CreateBcatService"}, + {1, C<&BcatInterface::CreateDeliveryCacheStorageService>, "CreateDeliveryCacheStorageService"}, + {2, C<&BcatInterface::CreateDeliveryCacheStorageServiceWithApplicationId>, "CreateDeliveryCacheStorageServiceWithApplicationId"}, + {3, nullptr, "CreateDeliveryCacheProgressService"}, + {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"}, + }; + // clang-format on + + RegisterHandlers(functions); + + backend = + CreateBackendFromSettings(system_, [this](u64 tid) { return fsc.GetBCATDirectory(tid); }); +} + +BcatInterface::~BcatInterface() = default; + +Result BcatInterface::CreateBcatService(OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system, *backend); + R_SUCCEED(); +} + +Result BcatInterface::CreateDeliveryCacheStorageService( + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + + const auto title_id = system.GetApplicationProcessProgramID(); + *out_interface = + std::make_shared(system, fsc.GetBCATDirectory(title_id)); + R_SUCCEED(); +} + +Result BcatInterface::CreateDeliveryCacheStorageServiceWithApplicationId( + u64 title_id, OutInterface out_interface) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); + *out_interface = + std::make_shared(system, fsc.GetBCATDirectory(title_id)); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_interface.h b/src/core/hle/service/bcat/bcat_interface.h new file mode 100644 index 000000000..9282b57bb --- /dev/null +++ b/src/core/hle/service/bcat/bcat_interface.h @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::FileSystem { +class FileSystemController; +} + +namespace Service::BCAT { +class BcatBackend; +class IBcatService; +class IDeliveryCacheStorageService; + +class BcatInterface final : public ServiceFramework { +public: + explicit BcatInterface(Core::System& system_, const char* name_); + ~BcatInterface() override; + +private: + Result CreateBcatService(OutInterface out_interface); + + Result CreateDeliveryCacheStorageService( + OutInterface out_interface); + + Result CreateDeliveryCacheStorageServiceWithApplicationId( + u64 title_id, OutInterface out_interface); + + std::unique_ptr backend; + Service::FileSystem::FileSystemController& fsc; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp deleted file mode 100644 index 76d7bb139..000000000 --- a/src/core/hle/service/bcat/bcat_module.cpp +++ /dev/null @@ -1,606 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include "common/hex_util.h" -#include "common/logging/log.h" -#include "common/settings.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/file_sys/vfs/vfs.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/bcat/backend/backend.h" -#include "core/hle/service/bcat/bcat.h" -#include "core/hle/service/bcat/bcat_module.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/server_manager.h" - -namespace Service::BCAT { - -constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::BCAT, 1}; -constexpr Result ERROR_FAILED_OPEN_ENTITY{ErrorModule::BCAT, 2}; -constexpr Result ERROR_ENTITY_ALREADY_OPEN{ErrorModule::BCAT, 6}; -constexpr Result ERROR_NO_OPEN_ENTITY{ErrorModule::BCAT, 7}; - -// The command to clear the delivery cache just calls fs IFileSystem DeleteFile on all of the files -// and if any of them have a non-zero result it just forwards that result. This is the FS error code -// for permission denied, which is the closest approximation of this scenario. -constexpr Result ERROR_FAILED_CLEAR_CACHE{ErrorModule::FS, 6400}; - -using BCATDigest = std::array; - -namespace { - -u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) { - u64 out{}; - std::memcpy(&out, id.data(), sizeof(u64)); - return out; -} - -// The digest is only used to determine if a file is unique compared to others of the same name. -// Since the algorithm isn't ever checked in game, MD5 is safe. -BCATDigest DigestFile(const FileSys::VirtualFile& file) { - BCATDigest out{}; - const auto bytes = file->ReadAllBytes(); - mbedtls_md5_ret(bytes.data(), bytes.size(), out.data()); - return out; -} - -// For a name to be valid it must be non-empty, must have a null terminating character as the final -// char, can only contain numbers, letters, underscores and a hyphen if directory and a period if -// file. -bool VerifyNameValidInternal(HLERequestContext& ctx, std::array name, char match_char) { - const auto null_chars = std::count(name.begin(), name.end(), 0); - const auto bad_chars = std::count_if(name.begin(), name.end(), [match_char](char c) { - return !std::isalnum(static_cast(c)) && c != '_' && c != match_char && c != '\0'; - }); - if (null_chars == 0x20 || null_chars == 0 || bad_chars != 0 || name[0x1F] != '\0') { - LOG_ERROR(Service_BCAT, "Name passed was invalid!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); - return false; - } - - return true; -} - -bool VerifyNameValidDir(HLERequestContext& ctx, DirectoryName name) { - return VerifyNameValidInternal(ctx, name, '-'); -} - -bool VerifyNameValidFile(HLERequestContext& ctx, FileName name) { - return VerifyNameValidInternal(ctx, name, '.'); -} - -} // Anonymous namespace - -struct DeliveryCacheDirectoryEntry { - FileName name; - u64 size; - BCATDigest digest; -}; - -class IDeliveryCacheProgressService final : public ServiceFramework { -public: - explicit IDeliveryCacheProgressService(Core::System& system_, Kernel::KReadableEvent& event_, - const DeliveryCacheProgressImpl& impl_) - : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{event_}, impl{impl_} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IDeliveryCacheProgressService::GetEvent, "GetEvent"}, - {1, &IDeliveryCacheProgressService::GetImpl, "GetImpl"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void GetEvent(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event); - } - - void GetImpl(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - ctx.WriteBuffer(impl); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - Kernel::KReadableEvent& event; - const DeliveryCacheProgressImpl& impl; -}; - -class IBcatService final : public ServiceFramework { -public: - explicit IBcatService(Core::System& system_, Backend& backend_) - : ServiceFramework{system_, "IBcatService"}, backend{backend_}, - progress{{ - ProgressServiceBackend{system_, "Normal"}, - ProgressServiceBackend{system_, "Directory"}, - }} { - // clang-format off - static const FunctionInfo functions[] = { - {10100, &IBcatService::RequestSyncDeliveryCache, "RequestSyncDeliveryCache"}, - {10101, &IBcatService::RequestSyncDeliveryCacheWithDirectoryName, "RequestSyncDeliveryCacheWithDirectoryName"}, - {10200, nullptr, "CancelSyncDeliveryCacheRequest"}, - {20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"}, - {20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"}, - {20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"}, - {20301, nullptr, "RequestSuspendDeliveryTask"}, - {20400, nullptr, "RegisterSystemApplicationDeliveryTask"}, - {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"}, - {20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"}, - {30100, &IBcatService::SetPassphrase, "SetPassphrase"}, - {30101, nullptr, "Unknown30101"}, - {30102, nullptr, "Unknown30102"}, - {30200, nullptr, "RegisterBackgroundDeliveryTask"}, - {30201, nullptr, "UnregisterBackgroundDeliveryTask"}, - {30202, nullptr, "BlockDeliveryTask"}, - {30203, nullptr, "UnblockDeliveryTask"}, - {30210, nullptr, "SetDeliveryTaskTimer"}, - {30300, nullptr, "RegisterSystemApplicationDeliveryTasks"}, - {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, - {90101, nullptr, "Unknown90101"}, - {90200, nullptr, "GetDeliveryList"}, - {90201, &IBcatService::ClearDeliveryCacheStorage, "ClearDeliveryCacheStorage"}, - {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"}, - {90300, nullptr, "GetPushNotificationLog"}, - {90301, nullptr, "Unknown90301"}, - }; - // clang-format on - RegisterHandlers(functions); - } - -private: - enum class SyncType { - Normal, - Directory, - Count, - }; - - std::shared_ptr CreateProgressService(SyncType type) { - auto& progress_backend{GetProgressBackend(type)}; - return std::make_shared(system, progress_backend.GetEvent(), - progress_backend.GetImpl()); - } - - void RequestSyncDeliveryCache(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - backend.Synchronize({system.GetApplicationProcessProgramID(), - GetCurrentBuildID(system.GetApplicationProcessBuildID())}, - GetProgressBackend(SyncType::Normal)); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(CreateProgressService(SyncType::Normal)); - } - - void RequestSyncDeliveryCacheWithDirectoryName(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto name_raw = rp.PopRaw(); - const auto name = - Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size()); - - LOG_DEBUG(Service_BCAT, "called, name={}", name); - - backend.SynchronizeDirectory({system.GetApplicationProcessProgramID(), - GetCurrentBuildID(system.GetApplicationProcessBuildID())}, - name, GetProgressBackend(SyncType::Directory)); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(CreateProgressService(SyncType::Directory)); - } - - void SetPassphrase(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto title_id = rp.PopRaw(); - - const auto passphrase_raw = ctx.ReadBuffer(); - - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, - Common::HexToString(passphrase_raw)); - - if (title_id == 0) { - LOG_ERROR(Service_BCAT, "Invalid title ID!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); - } - - if (passphrase_raw.size() > 0x40) { - LOG_ERROR(Service_BCAT, "Passphrase too large!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); - return; - } - - Passphrase passphrase{}; - std::memcpy(passphrase.data(), passphrase_raw.data(), - std::min(passphrase.size(), passphrase_raw.size())); - - backend.SetPassphrase(title_id, passphrase); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void ClearDeliveryCacheStorage(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto title_id = rp.PopRaw(); - - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); - - if (title_id == 0) { - LOG_ERROR(Service_BCAT, "Invalid title ID!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); - return; - } - - if (!backend.Clear(title_id)) { - LOG_ERROR(Service_BCAT, "Could not clear the directory successfully!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_FAILED_CLEAR_CACHE); - return; - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - ProgressServiceBackend& GetProgressBackend(SyncType type) { - return progress.at(static_cast(type)); - } - - const ProgressServiceBackend& GetProgressBackend(SyncType type) const { - return progress.at(static_cast(type)); - } - - Backend& backend; - std::array(SyncType::Count)> progress; -}; - -void Module::Interface::CreateBcatService(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, *backend); -} - -class IDeliveryCacheFileService final : public ServiceFramework { -public: - explicit IDeliveryCacheFileService(Core::System& system_, FileSys::VirtualDir root_) - : ServiceFramework{system_, "IDeliveryCacheFileService"}, root(std::move(root_)) { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IDeliveryCacheFileService::Open, "Open"}, - {1, &IDeliveryCacheFileService::Read, "Read"}, - {2, &IDeliveryCacheFileService::GetSize, "GetSize"}, - {3, &IDeliveryCacheFileService::GetDigest, "GetDigest"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void Open(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto dir_name_raw = rp.PopRaw(); - const auto file_name_raw = rp.PopRaw(); - - const auto dir_name = - Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size()); - const auto file_name = - Common::StringFromFixedZeroTerminatedBuffer(file_name_raw.data(), file_name_raw.size()); - - LOG_DEBUG(Service_BCAT, "called, dir_name={}, file_name={}", dir_name, file_name); - - if (!VerifyNameValidDir(ctx, dir_name_raw) || !VerifyNameValidFile(ctx, file_name_raw)) - return; - - if (current_file != nullptr) { - LOG_ERROR(Service_BCAT, "A file has already been opened on this interface!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_ENTITY_ALREADY_OPEN); - return; - } - - const auto dir = root->GetSubdirectory(dir_name); - - if (dir == nullptr) { - LOG_ERROR(Service_BCAT, "The directory of name={} couldn't be opened!", dir_name); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_FAILED_OPEN_ENTITY); - return; - } - - current_file = dir->GetFile(file_name); - - if (current_file == nullptr) { - LOG_ERROR(Service_BCAT, "The file of name={} couldn't be opened!", file_name); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_FAILED_OPEN_ENTITY); - return; - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void Read(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto offset{rp.PopRaw()}; - - auto size = ctx.GetWriteBufferSize(); - - LOG_DEBUG(Service_BCAT, "called, offset={:016X}, size={:016X}", offset, size); - - if (current_file == nullptr) { - LOG_ERROR(Service_BCAT, "There is no file currently open!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_NO_OPEN_ENTITY); - } - - size = std::min(current_file->GetSize() - offset, size); - const auto buffer = current_file->ReadBytes(size, offset); - ctx.WriteBuffer(buffer); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(buffer.size()); - } - - void GetSize(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - if (current_file == nullptr) { - LOG_ERROR(Service_BCAT, "There is no file currently open!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_NO_OPEN_ENTITY); - } - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(current_file->GetSize()); - } - - void GetDigest(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - if (current_file == nullptr) { - LOG_ERROR(Service_BCAT, "There is no file currently open!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_NO_OPEN_ENTITY); - } - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(ResultSuccess); - rb.PushRaw(DigestFile(current_file)); - } - - FileSys::VirtualDir root; - FileSys::VirtualFile current_file; -}; - -class IDeliveryCacheDirectoryService final - : public ServiceFramework { -public: - explicit IDeliveryCacheDirectoryService(Core::System& system_, FileSys::VirtualDir root_) - : ServiceFramework{system_, "IDeliveryCacheDirectoryService"}, root(std::move(root_)) { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IDeliveryCacheDirectoryService::Open, "Open"}, - {1, &IDeliveryCacheDirectoryService::Read, "Read"}, - {2, &IDeliveryCacheDirectoryService::GetCount, "GetCount"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void Open(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto name_raw = rp.PopRaw(); - const auto name = - Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size()); - - LOG_DEBUG(Service_BCAT, "called, name={}", name); - - if (!VerifyNameValidDir(ctx, name_raw)) - return; - - if (current_dir != nullptr) { - LOG_ERROR(Service_BCAT, "A file has already been opened on this interface!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_ENTITY_ALREADY_OPEN); - return; - } - - current_dir = root->GetSubdirectory(name); - - if (current_dir == nullptr) { - LOG_ERROR(Service_BCAT, "Failed to open the directory name={}!", name); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_FAILED_OPEN_ENTITY); - return; - } - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void Read(HLERequestContext& ctx) { - auto write_size = ctx.GetWriteBufferNumElements(); - - LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", write_size); - - if (current_dir == nullptr) { - LOG_ERROR(Service_BCAT, "There is no open directory!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_NO_OPEN_ENTITY); - return; - } - - const auto files = current_dir->GetFiles(); - write_size = std::min(write_size, files.size()); - std::vector entries(write_size); - std::transform( - files.begin(), files.begin() + write_size, entries.begin(), [](const auto& file) { - FileName name{}; - std::memcpy(name.data(), file->GetName().data(), - std::min(file->GetName().size(), name.size())); - return DeliveryCacheDirectoryEntry{name, file->GetSize(), DigestFile(file)}; - }); - - ctx.WriteBuffer(entries); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(write_size * sizeof(DeliveryCacheDirectoryEntry))); - } - - void GetCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - if (current_dir == nullptr) { - LOG_ERROR(Service_BCAT, "There is no open directory!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_NO_OPEN_ENTITY); - return; - } - - const auto files = current_dir->GetFiles(); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(files.size())); - } - - FileSys::VirtualDir root; - FileSys::VirtualDir current_dir; -}; - -class IDeliveryCacheStorageService final : public ServiceFramework { -public: - explicit IDeliveryCacheStorageService(Core::System& system_, FileSys::VirtualDir root_) - : ServiceFramework{system_, "IDeliveryCacheStorageService"}, root(std::move(root_)) { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IDeliveryCacheStorageService::CreateFileService, "CreateFileService"}, - {1, &IDeliveryCacheStorageService::CreateDirectoryService, "CreateDirectoryService"}, - {10, &IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory, "EnumerateDeliveryCacheDirectory"}, - }; - // clang-format on - - RegisterHandlers(functions); - - for (const auto& subdir : root->GetSubdirectories()) { - DirectoryName name{}; - std::memcpy(name.data(), subdir->GetName().data(), - std::min(sizeof(DirectoryName) - 1, subdir->GetName().size())); - entries.push_back(name); - } - } - -private: - void CreateFileService(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, root); - } - - void CreateDirectoryService(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, root); - } - - void EnumerateDeliveryCacheDirectory(HLERequestContext& ctx) { - auto size = ctx.GetWriteBufferNumElements(); - - LOG_DEBUG(Service_BCAT, "called, size={:016X}", size); - - size = std::min(size, entries.size() - next_read_index); - ctx.WriteBuffer(entries.data() + next_read_index, size * sizeof(DirectoryName)); - next_read_index += size; - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(size)); - } - - FileSys::VirtualDir root; - std::vector entries; - u64 next_read_index = 0; -}; - -void Module::Interface::CreateDeliveryCacheStorageService(HLERequestContext& ctx) { - LOG_DEBUG(Service_BCAT, "called"); - - const auto title_id = system.GetApplicationProcessProgramID(); - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, fsc.GetBCATDirectory(title_id)); -} - -void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto title_id = rp.PopRaw(); - - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, fsc.GetBCATDirectory(title_id)); -} - -std::unique_ptr CreateBackendFromSettings([[maybe_unused]] Core::System& system, - DirectoryGetter getter) { - return std::make_unique(std::move(getter)); -} - -Module::Interface::Interface(Core::System& system_, std::shared_ptr module_, - FileSystem::FileSystemController& fsc_, const char* name) - : ServiceFramework{system_, name}, fsc{fsc_}, module{std::move(module_)}, - backend{CreateBackendFromSettings(system_, - [&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })} {} - -Module::Interface::~Interface() = default; - -void LoopProcess(Core::System& system) { - auto server_manager = std::make_unique(system); - auto module = std::make_shared(); - - server_manager->RegisterNamedService( - "bcat:a", - std::make_shared(system, module, system.GetFileSystemController(), "bcat:a")); - server_manager->RegisterNamedService( - "bcat:m", - std::make_shared(system, module, system.GetFileSystemController(), "bcat:m")); - server_manager->RegisterNamedService( - "bcat:u", - std::make_shared(system, module, system.GetFileSystemController(), "bcat:u")); - server_manager->RegisterNamedService( - "bcat:s", - std::make_shared(system, module, system.GetFileSystemController(), "bcat:s")); - ServerManager::RunServer(std::move(server_manager)); -} - -} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_module.h b/src/core/hle/service/bcat/bcat_module.h deleted file mode 100644 index 87576288b..000000000 --- a/src/core/hle/service/bcat/bcat_module.h +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service { - -namespace FileSystem { -class FileSystemController; -} // namespace FileSystem - -namespace BCAT { - -class Backend; - -class Module final { -public: - class Interface : public ServiceFramework { - public: - explicit Interface(Core::System& system_, std::shared_ptr module_, - FileSystem::FileSystemController& fsc_, const char* name); - ~Interface() override; - - void CreateBcatService(HLERequestContext& ctx); - void CreateDeliveryCacheStorageService(HLERequestContext& ctx); - void CreateDeliveryCacheStorageServiceWithApplicationId(HLERequestContext& ctx); - - protected: - FileSystem::FileSystemController& fsc; - - std::shared_ptr module; - std::unique_ptr backend; - }; -}; - -void LoopProcess(Core::System& system); - -} // namespace BCAT - -} // namespace Service diff --git a/src/core/hle/service/bcat/bcat_result.h b/src/core/hle/service/bcat/bcat_result.h new file mode 100644 index 000000000..d711924b1 --- /dev/null +++ b/src/core/hle/service/bcat/bcat_result.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/result.h" + +namespace Service::BCAT { + +constexpr Result ResultInvalidArgument{ErrorModule::BCAT, 1}; +constexpr Result ResultFailedOpenEntity{ErrorModule::BCAT, 2}; +constexpr Result ResultEntityAlreadyOpen{ErrorModule::BCAT, 6}; +constexpr Result ResultNoOpenEntry{ErrorModule::BCAT, 7}; + +// The command to clear the delivery cache just calls fs IFileSystem DeleteFile on all of the +// files and if any of them have a non-zero result it just forwards that result. This is the FS +// error code for permission denied, which is the closest approximation of this scenario. +constexpr Result ResultFailedClearCache{ErrorModule::FS, 6400}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_service.cpp b/src/core/hle/service/bcat/bcat_service.cpp new file mode 100644 index 000000000..2eacec3ae --- /dev/null +++ b/src/core/hle/service/bcat/bcat_service.cpp @@ -0,0 +1,131 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/hex_util.h" +#include "common/string_util.h" +#include "core/core.h" +#include "core/hle/service/bcat/backend/backend.h" +#include "core/hle/service/bcat/bcat_result.h" +#include "core/hle/service/bcat/bcat_service.h" +#include "core/hle/service/bcat/bcat_util.h" +#include "core/hle/service/bcat/delivery_cache_progress_service.h" +#include "core/hle/service/bcat/delivery_cache_storage_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) { + u64 out{}; + std::memcpy(&out, id.data(), sizeof(u64)); + return out; +} + +IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_) + : ServiceFramework{system_, "IBcatService"}, backend{backend_}, + progress{{ + ProgressServiceBackend{system_, "Normal"}, + ProgressServiceBackend{system_, "Directory"}, + }} { + // clang-format off + static const FunctionInfo functions[] = { + {10100, C<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"}, + {10101, C<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"}, + {10200, nullptr, "CancelSyncDeliveryCacheRequest"}, + {20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"}, + {20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"}, + {20300, nullptr, "GetDeliveryCacheStorageUpdateNotifier"}, + {20301, nullptr, "RequestSuspendDeliveryTask"}, + {20400, nullptr, "RegisterSystemApplicationDeliveryTask"}, + {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"}, + {20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"}, + {30100, C<&IBcatService::SetPassphrase>, "SetPassphrase"}, + {30101, nullptr, "Unknown30101"}, + {30102, nullptr, "Unknown30102"}, + {30200, nullptr, "RegisterBackgroundDeliveryTask"}, + {30201, nullptr, "UnregisterBackgroundDeliveryTask"}, + {30202, nullptr, "BlockDeliveryTask"}, + {30203, nullptr, "UnblockDeliveryTask"}, + {30210, nullptr, "SetDeliveryTaskTimer"}, + {30300, C<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"}, + {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, + {90101, nullptr, "Unknown90101"}, + {90200, nullptr, "GetDeliveryList"}, + {90201, C<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"}, + {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"}, + {90300, nullptr, "GetPushNotificationLog"}, + {90301, nullptr, "Unknown90301"}, + }; + // clang-format on + RegisterHandlers(functions); +} + +IBcatService::~IBcatService() = default; + +Result IBcatService::RequestSyncDeliveryCache( + OutInterface out_interface) { + LOG_DEBUG(Service_BCAT, "called"); + + auto& progress_backend{GetProgressBackend(SyncType::Normal)}; + backend.Synchronize({system.GetApplicationProcessProgramID(), + GetCurrentBuildID(system.GetApplicationProcessBuildID())}, + GetProgressBackend(SyncType::Normal)); + + *out_interface = std::make_shared( + system, progress_backend.GetEvent(), progress_backend.GetImpl()); + R_SUCCEED(); +} + +Result IBcatService::RequestSyncDeliveryCacheWithDirectoryName( + DirectoryName name_raw, OutInterface out_interface) { + const auto name = Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size()); + + LOG_DEBUG(Service_BCAT, "called, name={}", name); + + auto& progress_backend{GetProgressBackend(SyncType::Directory)}; + backend.SynchronizeDirectory({system.GetApplicationProcessProgramID(), + GetCurrentBuildID(system.GetApplicationProcessBuildID())}, + name, progress_backend); + + *out_interface = std::make_shared( + system, progress_backend.GetEvent(), progress_backend.GetImpl()); + R_SUCCEED(); +} + +Result IBcatService::SetPassphrase(u64 title_id, + InBuffer passphrase_buffer) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, + Common::HexToString(passphrase_buffer)); + + R_UNLESS(title_id != 0, ResultInvalidArgument); + R_UNLESS(passphrase_buffer.size() <= 0x40, ResultInvalidArgument); + + Passphrase passphrase{}; + std::memcpy(passphrase.data(), passphrase_buffer.data(), + std::min(passphrase.size(), passphrase_buffer.size())); + + backend.SetPassphrase(title_id, passphrase); + R_SUCCEED(); +} + +Result IBcatService::RegisterSystemApplicationDeliveryTasks() { + LOG_WARNING(Service_BCAT, "(STUBBED) called"); + R_SUCCEED(); +} + +Result IBcatService::ClearDeliveryCacheStorage(u64 title_id) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); + + R_UNLESS(title_id != 0, ResultInvalidArgument); + R_UNLESS(backend.Clear(title_id), ResultFailedClearCache); + R_SUCCEED(); +} + +ProgressServiceBackend& IBcatService::GetProgressBackend(SyncType type) { + return progress.at(static_cast(type)); +} + +const ProgressServiceBackend& IBcatService::GetProgressBackend(SyncType type) const { + return progress.at(static_cast(type)); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_service.h b/src/core/hle/service/bcat/bcat_service.h new file mode 100644 index 000000000..3e1ed98c3 --- /dev/null +++ b/src/core/hle/service/bcat/bcat_service.h @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/bcat/backend/backend.h" +#include "core/hle/service/bcat/bcat_types.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { +class BcatBackend; +class IDeliveryCacheStorageService; +class IDeliveryCacheProgressService; + +class IBcatService final : public ServiceFramework { +public: + explicit IBcatService(Core::System& system_, BcatBackend& backend_); + ~IBcatService() override; + +private: + Result RequestSyncDeliveryCache(OutInterface out_interface); + + Result RequestSyncDeliveryCacheWithDirectoryName( + DirectoryName name, OutInterface out_interface); + + Result SetPassphrase(u64 title_id, InBuffer passphrase_buffer); + + Result RegisterSystemApplicationDeliveryTasks(); + + Result ClearDeliveryCacheStorage(u64 title_id); + +private: + ProgressServiceBackend& GetProgressBackend(SyncType type); + const ProgressServiceBackend& GetProgressBackend(SyncType type) const; + + BcatBackend& backend; + std::array(SyncType::Count)> progress; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_types.h b/src/core/hle/service/bcat/bcat_types.h new file mode 100644 index 000000000..a56f9248f --- /dev/null +++ b/src/core/hle/service/bcat/bcat_types.h @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "core/file_sys/vfs/vfs_types.h" + +namespace Service::BCAT { + +using DirectoryName = std::array; +using FileName = std::array; +using BcatDigest = std::array; +using Passphrase = std::array; +using DirectoryGetter = std::function; + +enum class SyncType { + Normal, + Directory, + Count, +}; + +enum class DeliveryCacheProgressStatus : s32 { + None = 0x0, + Queued = 0x1, + Connecting = 0x2, + ProcessingDataList = 0x3, + Downloading = 0x4, + Committing = 0x5, + Done = 0x9, +}; + +struct DeliveryCacheDirectoryEntry { + FileName name; + u64 size; + BcatDigest digest; +}; + +struct TitleIDVersion { + u64 title_id; + u64 build_id; +}; + +struct DeliveryCacheProgressImpl { + DeliveryCacheProgressStatus status; + Result result = ResultSuccess; + DirectoryName current_directory; + FileName current_file; + s64 current_downloaded_bytes; ///< Bytes downloaded on current file. + s64 current_total_bytes; ///< Bytes total on current file. + s64 total_downloaded_bytes; ///< Bytes downloaded on overall download. + s64 total_bytes; ///< Bytes total on overall download. + INSERT_PADDING_BYTES( + 0x198); ///< Appears to be unused in official code, possibly reserved for future use. +}; +static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200, + "DeliveryCacheProgressImpl has incorrect size."); + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_util.h b/src/core/hle/service/bcat/bcat_util.h new file mode 100644 index 000000000..6bf2657ee --- /dev/null +++ b/src/core/hle/service/bcat/bcat_util.h @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include +#include + +#include "core/hle/service/bcat/bcat_result.h" +#include "core/hle/service/bcat/bcat_types.h" + +namespace Service::BCAT { + +// For a name to be valid it must be non-empty, must have a null terminating character as the final +// char, can only contain numbers, letters, underscores and a hyphen if directory and a period if +// file. +constexpr Result VerifyNameValidInternal(std::array name, char match_char) { + const auto null_chars = std::count(name.begin(), name.end(), 0); + const auto bad_chars = std::count_if(name.begin(), name.end(), [match_char](char c) { + return !std::isalnum(static_cast(c)) && c != '_' && c != match_char && c != '\0'; + }); + if (null_chars == 0x20 || null_chars == 0 || bad_chars != 0 || name[0x1F] != '\0') { + LOG_ERROR(Service_BCAT, "Name passed was invalid!"); + return ResultInvalidArgument; + } + + return ResultSuccess; +} + +constexpr Result VerifyNameValidDir(DirectoryName name) { + return VerifyNameValidInternal(name, '-'); +} + +constexpr Result VerifyNameValidFile(FileName name) { + return VerifyNameValidInternal(name, '.'); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.cpp b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp new file mode 100644 index 000000000..8bda1168a --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "common/string_util.h" +#include "core/file_sys/vfs/vfs_types.h" +#include "core/hle/service/bcat/bcat_result.h" +#include "core/hle/service/bcat/bcat_util.h" +#include "core/hle/service/bcat/delivery_cache_directory_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +// The digest is only used to determine if a file is unique compared to others of the same name. +// Since the algorithm isn't ever checked in game, MD5 is safe. +BcatDigest DigestFile(const FileSys::VirtualFile& file) { + BcatDigest out{}; + const auto bytes = file->ReadAllBytes(); + mbedtls_md5_ret(bytes.data(), bytes.size(), out.data()); + return out; +} + +IDeliveryCacheDirectoryService::IDeliveryCacheDirectoryService(Core::System& system_, + FileSys::VirtualDir root_) + : ServiceFramework{system_, "IDeliveryCacheDirectoryService"}, root(std::move(root_)) { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IDeliveryCacheDirectoryService::Open>, "Open"}, + {1, C<&IDeliveryCacheDirectoryService::Read>, "Read"}, + {2, C<&IDeliveryCacheDirectoryService::GetCount>, "GetCount"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IDeliveryCacheDirectoryService::~IDeliveryCacheDirectoryService() = default; + +Result IDeliveryCacheDirectoryService::Open(DirectoryName dir_name_raw) { + const auto dir_name = + Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size()); + + LOG_DEBUG(Service_BCAT, "called, dir_name={}", dir_name); + + // R_TRY(VerifyNameValidDir(dir_name_raw)); + R_UNLESS(current_dir == nullptr, ResultEntityAlreadyOpen); + + const auto dir = root->GetSubdirectory(dir_name); + R_UNLESS(dir != nullptr, ResultFailedOpenEntity); + + R_SUCCEED(); +} + +Result IDeliveryCacheDirectoryService::Read( + Out out_buffer_size, + OutArray out_buffer) { + LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", out_buffer.size()); + + R_UNLESS(current_dir != nullptr, ResultNoOpenEntry); + + const auto files = current_dir->GetFiles(); + *out_buffer_size = static_cast(std::min(files.size(), out_buffer.size())); + std::transform(files.begin(), files.begin() + *out_buffer_size, out_buffer.begin(), + [](const auto& file) { + FileName name{}; + std::memcpy(name.data(), file->GetName().data(), + std::min(file->GetName().size(), name.size())); + return DeliveryCacheDirectoryEntry{name, file->GetSize(), DigestFile(file)}; + }); + R_SUCCEED(); +} + +Result IDeliveryCacheDirectoryService::GetCount(Out out_count) { + LOG_DEBUG(Service_BCAT, "called"); + + R_UNLESS(current_dir != nullptr, ResultNoOpenEntry); + + *out_count = static_cast(current_dir->GetFiles().size()); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.h b/src/core/hle/service/bcat/delivery_cache_directory_service.h new file mode 100644 index 000000000..f544d0947 --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_directory_service.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/bcat/bcat_types.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { + +class IDeliveryCacheDirectoryService final + : public ServiceFramework { +public: + explicit IDeliveryCacheDirectoryService(Core::System& system_, FileSys::VirtualDir root_); + ~IDeliveryCacheDirectoryService() override; + +private: + Result Open(DirectoryName dir_name_raw); + Result Read(Out out_buffer_size, + OutArray out_buffer); + Result GetCount(Out out_count); + + FileSys::VirtualDir root; + FileSys::VirtualDir current_dir; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_file_service.cpp b/src/core/hle/service/bcat/delivery_cache_file_service.cpp new file mode 100644 index 000000000..c91efd47e --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_file_service.cpp @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "common/string_util.h" +#include "core/hle/service/bcat/bcat_result.h" +#include "core/hle/service/bcat/bcat_util.h" +#include "core/hle/service/bcat/delivery_cache_file_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +IDeliveryCacheFileService::IDeliveryCacheFileService(Core::System& system_, + FileSys::VirtualDir root_) + : ServiceFramework{system_, "IDeliveryCacheFileService"}, root(std::move(root_)) { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IDeliveryCacheFileService::Open>, "Open"}, + {1, C<&IDeliveryCacheFileService::Read>, "Read"}, + {2, C<&IDeliveryCacheFileService::GetSize>, "GetSize"}, + {3, C<&IDeliveryCacheFileService::GetDigest>, "GetDigest"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IDeliveryCacheFileService::~IDeliveryCacheFileService() = default; + +Result IDeliveryCacheFileService::Open(DirectoryName dir_name_raw, FileName file_name_raw) { + const auto dir_name = + Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size()); + const auto file_name = + Common::StringFromFixedZeroTerminatedBuffer(file_name_raw.data(), file_name_raw.size()); + + LOG_DEBUG(Service_BCAT, "called, dir_name={}, file_name={}", dir_name, file_name); + + R_TRY(VerifyNameValidDir(dir_name_raw)); + R_TRY(VerifyNameValidDir(file_name_raw)); + R_UNLESS(current_file == nullptr, ResultEntityAlreadyOpen); + + const auto dir = root->GetSubdirectory(dir_name); + R_UNLESS(dir != nullptr, ResultFailedOpenEntity); + + current_file = dir->GetFile(file_name); + R_UNLESS(current_file != nullptr, ResultFailedOpenEntity); + + R_SUCCEED(); +} + +Result IDeliveryCacheFileService::Read(Out out_buffer_size, u64 offset, + OutBuffer out_buffer) { + LOG_DEBUG(Service_BCAT, "called, offset={:016X}, size={:016X}", offset, out_buffer.size()); + + R_UNLESS(current_file != nullptr, ResultNoOpenEntry); + + *out_buffer_size = std::min(current_file->GetSize() - offset, out_buffer.size()); + const auto buffer = current_file->ReadBytes(*out_buffer_size, offset); + memcpy(out_buffer.data(), buffer.data(), buffer.size()); + + R_SUCCEED(); +} + +Result IDeliveryCacheFileService::GetSize(Out out_size) { + LOG_DEBUG(Service_BCAT, "called"); + + R_UNLESS(current_file != nullptr, ResultNoOpenEntry); + + *out_size = current_file->GetSize(); + R_SUCCEED(); +} + +Result IDeliveryCacheFileService::GetDigest(Out out_digest) { + LOG_DEBUG(Service_BCAT, "called"); + + R_UNLESS(current_file != nullptr, ResultNoOpenEntry); + + //*out_digest = DigestFile(current_file); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_file_service.h b/src/core/hle/service/bcat/delivery_cache_file_service.h new file mode 100644 index 000000000..7583b4d1d --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_file_service.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/bcat/bcat_types.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { + +class IDeliveryCacheFileService final : public ServiceFramework { +public: + explicit IDeliveryCacheFileService(Core::System& system_, FileSys::VirtualDir root_); + ~IDeliveryCacheFileService() override; + +private: + Result Open(DirectoryName dir_name_raw, FileName file_name_raw); + Result Read(Out out_buffer_size, u64 offset, + OutBuffer out_buffer); + Result GetSize(Out out_size); + Result GetDigest(Out out_digest); + + FileSys::VirtualDir root; + FileSys::VirtualFile current_file; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_progress_service.cpp b/src/core/hle/service/bcat/delivery_cache_progress_service.cpp new file mode 100644 index 000000000..94d341f7e --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_progress_service.cpp @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/bcat_types.h" +#include "core/hle/service/bcat/delivery_cache_progress_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +IDeliveryCacheProgressService::IDeliveryCacheProgressService(Core::System& system_, + Kernel::KReadableEvent& event_, + const DeliveryCacheProgressImpl& impl_) + : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{event_}, impl{impl_} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IDeliveryCacheProgressService::GetEvent>, "Get"}, + {0, C<&IDeliveryCacheProgressService::GetImpl>, "Get"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IDeliveryCacheProgressService::~IDeliveryCacheProgressService() = default; + +Result IDeliveryCacheProgressService::GetEvent(OutCopyHandle out_event) { + LOG_DEBUG(Service_BCAT, "called"); + + *out_event = &event; + R_SUCCEED(); +} + +Result IDeliveryCacheProgressService::GetImpl( + OutLargeData out_impl) { + LOG_DEBUG(Service_BCAT, "called"); + + *out_impl = impl; + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_progress_service.h b/src/core/hle/service/bcat/delivery_cache_progress_service.h new file mode 100644 index 000000000..f81a13980 --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_progress_service.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Service::BCAT { +struct DeliveryCacheProgressImpl; + +class IDeliveryCacheProgressService final : public ServiceFramework { +public: + explicit IDeliveryCacheProgressService(Core::System& system_, Kernel::KReadableEvent& event_, + const DeliveryCacheProgressImpl& impl_); + ~IDeliveryCacheProgressService() override; + +private: + Result GetEvent(OutCopyHandle out_event); + Result GetImpl(OutLargeData out_impl); + + Kernel::KReadableEvent& event; + const DeliveryCacheProgressImpl& impl; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.cpp b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp new file mode 100644 index 000000000..5d03df1e7 --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/bcat_result.h" +#include "core/hle/service/bcat/delivery_cache_directory_service.h" +#include "core/hle/service/bcat/delivery_cache_file_service.h" +#include "core/hle/service/bcat/delivery_cache_storage_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +IDeliveryCacheStorageService::IDeliveryCacheStorageService(Core::System& system_, + FileSys::VirtualDir root_) + : ServiceFramework{system_, "IDeliveryCacheStorageService"}, root(std::move(root_)) { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IDeliveryCacheStorageService::CreateFileService>, "CreateFileService"}, + {1, C<&IDeliveryCacheStorageService::CreateDirectoryService>, "CreateDirectoryService"}, + {2, C<&IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory>, "EnumerateDeliveryCacheDirectory"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IDeliveryCacheStorageService::~IDeliveryCacheStorageService() = default; + +Result IDeliveryCacheStorageService::CreateFileService( + OutInterface out_interface) { + LOG_DEBUG(Service_BCAT, "called"); + + *out_interface = std::make_shared(system, root); + R_SUCCEED(); +} + +Result IDeliveryCacheStorageService::CreateDirectoryService( + OutInterface out_interface) { + LOG_DEBUG(Service_BCAT, "called"); + + *out_interface = std::make_shared(system, root); + R_SUCCEED(); +} + +Result IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory( + Out out_directories_size, + OutArray out_directories) { + LOG_DEBUG(Service_BCAT, "called, size={:016X}", out_directories.size()); + + *out_directories_size = + static_cast(std::min(out_directories.size(), entries.size() - next_read_index)); + memcpy(out_directories.data(), entries.data() + next_read_index, + *out_directories_size * sizeof(DirectoryName)); + next_read_index += *out_directories_size; + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.h b/src/core/hle/service/bcat/delivery_cache_storage_service.h new file mode 100644 index 000000000..1e86d3dbf --- /dev/null +++ b/src/core/hle/service/bcat/delivery_cache_storage_service.h @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/file_sys/vfs/vfs.h" +#include "core/hle/service/bcat/bcat_types.h" +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { +class IDeliveryCacheFileService; +class IDeliveryCacheDirectoryService; + +class IDeliveryCacheStorageService final : public ServiceFramework { +public: + explicit IDeliveryCacheStorageService(Core::System& system_, FileSys::VirtualDir root_); + ~IDeliveryCacheStorageService() override; + +private: + Result CreateFileService(OutInterface out_interface); + Result CreateDirectoryService(OutInterface out_interface); + Result EnumerateDeliveryCacheDirectory( + Out out_directories_size, + OutArray out_directories); + + FileSys::VirtualDir root; + std::vector entries; + u64 next_read_index = 0; +}; + +} // namespace Service::BCAT -- cgit v1.2.3 From 909f7eb3d2d54050af667e7638171c0cc50c8f90 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Thu, 8 Feb 2024 22:48:53 -0600 Subject: service: bcat: Implement news interfaces --- src/core/CMakeLists.txt | 12 +++++ src/core/hle/service/bcat/bcat.cpp | 12 +++++ .../bcat/news/newly_arrived_event_holder.cpp | 32 +++++++++++ .../service/bcat/news/newly_arrived_event_holder.h | 33 ++++++++++++ .../hle/service/bcat/news/news_data_service.cpp | 25 +++++++++ src/core/hle/service/bcat/news/news_data_service.h | 20 +++++++ .../service/bcat/news/news_database_service.cpp | 35 ++++++++++++ .../hle/service/bcat/news/news_database_service.h | 24 +++++++++ src/core/hle/service/bcat/news/news_interface.cpp | 63 ++++++++++++++++++++++ src/core/hle/service/bcat/news/news_interface.h | 35 ++++++++++++ src/core/hle/service/bcat/news/news_service.cpp | 46 ++++++++++++++++ src/core/hle/service/bcat/news/news_service.h | 24 +++++++++ .../service/bcat/news/overwrite_event_holder.cpp | 31 +++++++++++ .../hle/service/bcat/news/overwrite_event_holder.h | 33 ++++++++++++ 14 files changed, 425 insertions(+) create mode 100644 src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp create mode 100644 src/core/hle/service/bcat/news/newly_arrived_event_holder.h create mode 100644 src/core/hle/service/bcat/news/news_data_service.cpp create mode 100644 src/core/hle/service/bcat/news/news_data_service.h create mode 100644 src/core/hle/service/bcat/news/news_database_service.cpp create mode 100644 src/core/hle/service/bcat/news/news_database_service.h create mode 100644 src/core/hle/service/bcat/news/news_interface.cpp create mode 100644 src/core/hle/service/bcat/news/news_interface.h create mode 100644 src/core/hle/service/bcat/news/news_service.cpp create mode 100644 src/core/hle/service/bcat/news/news_service.h create mode 100644 src/core/hle/service/bcat/news/overwrite_event_holder.cpp create mode 100644 src/core/hle/service/bcat/news/overwrite_event_holder.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 703e6050f..539e09894 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -512,6 +512,18 @@ add_library(core STATIC hle/service/audio/hwopus.h hle/service/bcat/backend/backend.cpp hle/service/bcat/backend/backend.h + hle/service/bcat/news/newly_arrived_event_holder.cpp + hle/service/bcat/news/newly_arrived_event_holder.h + hle/service/bcat/news/news_data_service.cpp + hle/service/bcat/news/news_data_service.h + hle/service/bcat/news/news_database_service.cpp + hle/service/bcat/news/news_database_service.h + hle/service/bcat/news/news_interface.cpp + hle/service/bcat/news/news_interface.h + hle/service/bcat/news/news_service.cpp + hle/service/bcat/news/news_service.h + hle/service/bcat/news/overwrite_event_holder.cpp + hle/service/bcat/news/overwrite_event_holder.h hle/service/bcat/bcat.cpp hle/service/bcat/bcat.h hle/service/bcat/bcat_interface.cpp diff --git a/src/core/hle/service/bcat/bcat.cpp b/src/core/hle/service/bcat/bcat.cpp index 31e9d8662..02995ddee 100644 --- a/src/core/hle/service/bcat/bcat.cpp +++ b/src/core/hle/service/bcat/bcat.cpp @@ -4,6 +4,7 @@ #include "core/hle/service/bcat/backend/backend.h" #include "core/hle/service/bcat/bcat.h" #include "core/hle/service/bcat/bcat_interface.h" +#include "core/hle/service/bcat/news/news_interface.h" #include "core/hle/service/server_manager.h" namespace Service::BCAT { @@ -20,6 +21,17 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService("bcat:s", std::make_shared(system, "bcat:s")); + server_manager->RegisterNamedService( + "news:a", std::make_shared(system, 0xffffffff, "news:a")); + server_manager->RegisterNamedService("news:p", + std::make_shared(system, 0x1, "news:p")); + server_manager->RegisterNamedService("news:c", + std::make_shared(system, 0x2, "news:c")); + server_manager->RegisterNamedService("news:v", + std::make_shared(system, 0x4, "news:v")); + server_manager->RegisterNamedService("news:m", + std::make_shared(system, 0xd, "news:m")); + ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp new file mode 100644 index 000000000..b3f9e4683 --- /dev/null +++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/newly_arrived_event_holder.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +INewlyArrivedEventHolder::INewlyArrivedEventHolder(Core::System& system_) + : ServiceFramework{system_, "INewlyArrivedEventHolder"}, service_context{ + system_, + "INewlyArrivedEventHolder"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&INewlyArrivedEventHolder::Get>, "Get"}, + }; + // clang-format on + + RegisterHandlers(functions); + arrived_event = service_context.CreateEvent("INewlyArrivedEventHolder::ArrivedEvent"); +} + +INewlyArrivedEventHolder::~INewlyArrivedEventHolder() = default; + +Result INewlyArrivedEventHolder::Get(OutCopyHandle out_event) { + LOG_INFO(Service_BCAT, "called"); + + *out_event = &arrived_event->GetReadableEvent(); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.h b/src/core/hle/service/bcat/news/newly_arrived_event_holder.h new file mode 100644 index 000000000..af19d81a7 --- /dev/null +++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Service::BCAT { + +class INewlyArrivedEventHolder final : public ServiceFramework { +public: + explicit INewlyArrivedEventHolder(Core::System& system_); + ~INewlyArrivedEventHolder() override; + +private: + Result Get(OutCopyHandle out_event); + + Kernel::KEvent* arrived_event; + KernelHelpers::ServiceContext service_context; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_data_service.cpp b/src/core/hle/service/bcat/news/news_data_service.cpp new file mode 100644 index 000000000..eba2e6064 --- /dev/null +++ b/src/core/hle/service/bcat/news/news_data_service.cpp @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/news_data_service.h" + +namespace Service::BCAT { + +INewsDataService::INewsDataService(Core::System& system_) + : ServiceFramework{system_, "INewsDataService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Open"}, + {1, nullptr, "OpenWithNewsRecordV1"}, + {2, nullptr, "Read"}, + {3, nullptr, "GetSize"}, + {1001, nullptr, "OpenWithNewsRecord"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +INewsDataService::~INewsDataService() = default; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_data_service.h b/src/core/hle/service/bcat/news/news_data_service.h new file mode 100644 index 000000000..441e0ea8e --- /dev/null +++ b/src/core/hle/service/bcat/news/news_data_service.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { + +class INewsDataService final : public ServiceFramework { +public: + explicit INewsDataService(Core::System& system_); + ~INewsDataService() override; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_database_service.cpp b/src/core/hle/service/bcat/news/news_database_service.cpp new file mode 100644 index 000000000..3b4b33901 --- /dev/null +++ b/src/core/hle/service/bcat/news/news_database_service.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/news_database_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +INewsDatabaseService::INewsDatabaseService(Core::System& system_) + : ServiceFramework{system_, "INewsDatabaseService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetListV1"}, + {1, C<&INewsDatabaseService::Count>, "Count"}, + {2, nullptr, "CountWithKey"}, + {3, nullptr, "UpdateIntegerValue"}, + {4, nullptr, "UpdateIntegerValueWithAddition"}, + {5, nullptr, "UpdateStringValue"}, + {1000, nullptr, "GetList"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +INewsDatabaseService::~INewsDatabaseService() = default; + +Result INewsDatabaseService::Count(Out out_count, + InBuffer buffer_data) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size()); + *out_count = 0; + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_database_service.h b/src/core/hle/service/bcat/news/news_database_service.h new file mode 100644 index 000000000..dd09a1662 --- /dev/null +++ b/src/core/hle/service/bcat/news/news_database_service.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { + +class INewsDatabaseService final : public ServiceFramework { +public: + explicit INewsDatabaseService(Core::System& system_); + ~INewsDatabaseService() override; + +private: + Result Count(Out out_count, InBuffer buffer_data); +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_interface.cpp b/src/core/hle/service/bcat/news/news_interface.cpp new file mode 100644 index 000000000..0eaef2ddc --- /dev/null +++ b/src/core/hle/service/bcat/news/news_interface.cpp @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/newly_arrived_event_holder.h" +#include "core/hle/service/bcat/news/news_data_service.h" +#include "core/hle/service/bcat/news/news_database_service.h" +#include "core/hle/service/bcat/news/news_interface.h" +#include "core/hle/service/bcat/news/news_service.h" +#include "core/hle/service/bcat/news/overwrite_event_holder.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +NewsInterface::NewsInterface(Core::System& system_, u32 permissions_, const char* name_) + : ServiceFramework{system_, name_}, permissions{permissions_} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&NewsInterface::CreateNewsService>, "CreateNewsService"}, + {1, C<&NewsInterface::CreateNewlyArrivedEventHolder>, "CreateNewlyArrivedEventHolder"}, + {2, C<&NewsInterface::CreateNewsDataService>, "CreateNewsDataService"}, + {3, C<&NewsInterface::CreateNewsDatabaseService>, "CreateNewsDatabaseService"}, + {4, C<&NewsInterface::CreateOverwriteEventHolder>, "CreateOverwriteEventHolder"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +NewsInterface::~NewsInterface() = default; + +Result NewsInterface::CreateNewsService(OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result NewsInterface::CreateNewlyArrivedEventHolder( + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result NewsInterface::CreateNewsDataService(OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result NewsInterface::CreateNewsDatabaseService(OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result NewsInterface::CreateOverwriteEventHolder( + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_interface.h b/src/core/hle/service/bcat/news/news_interface.h new file mode 100644 index 000000000..d95edba3d --- /dev/null +++ b/src/core/hle/service/bcat/news/news_interface.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { +class INewsService; +class INewlyArrivedEventHolder; +class INewsDataService; +class INewsDatabaseService; +class IOverwriteEventHolder; + +class NewsInterface final : public ServiceFramework { +public: + explicit NewsInterface(Core::System& system_, u32 permissions_, const char* name_); + ~NewsInterface() override; + +private: + Result CreateNewsService(OutInterface out_interface); + Result CreateNewlyArrivedEventHolder(OutInterface out_interface); + Result CreateNewsDataService(OutInterface out_interface); + Result CreateNewsDatabaseService(OutInterface out_interface); + Result CreateOverwriteEventHolder(OutInterface out_interface); + + u32 permissions; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_service.cpp b/src/core/hle/service/bcat/news/news_service.cpp new file mode 100644 index 000000000..372937351 --- /dev/null +++ b/src/core/hle/service/bcat/news/news_service.cpp @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/news_service.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +INewsService::INewsService(Core::System& system_) : ServiceFramework{system_, "INewsService"} { + // clang-format off + static const FunctionInfo functions[] = { + {10100, nullptr, "PostLocalNews"}, + {20100, nullptr, "SetPassphrase"}, + {30100, C<&INewsService::GetSubscriptionStatus>, "GetSubscriptionStatus"}, + {30101, nullptr, "GetTopicList"}, + {30110, nullptr, "Unknown30110"}, + {30200, nullptr, "IsSystemUpdateRequired"}, + {30201, nullptr, "Unknown30201"}, + {30210, nullptr, "Unknown30210"}, + {30300, nullptr, "RequestImmediateReception"}, + {30400, nullptr, "DecodeArchiveFile"}, + {30500, nullptr, "Unknown30500"}, + {30900, nullptr, "Unknown30900"}, + {30901, nullptr, "Unknown30901"}, + {30902, nullptr, "Unknown30902"}, + {40100, nullptr, "SetSubscriptionStatus"}, + {40101, nullptr, "RequestAutoSubscription"}, + {40200, nullptr, "ClearStorage"}, + {40201, nullptr, "ClearSubscriptionStatusAll"}, + {90100, nullptr, "GetNewsDatabaseDump"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +INewsService::~INewsService() = default; + +Result INewsService::GetSubscriptionStatus(Out out_status, + InBuffer buffer_data) { + LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size()); + *out_status = 0; + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_service.h b/src/core/hle/service/bcat/news/news_service.h new file mode 100644 index 000000000..bb2e49848 --- /dev/null +++ b/src/core/hle/service/bcat/news/news_service.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::BCAT { + +class INewsService final : public ServiceFramework { +public: + explicit INewsService(Core::System& system_); + ~INewsService() override; + +private: + Result GetSubscriptionStatus(Out out_status, InBuffer buffer_data); +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.cpp b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp new file mode 100644 index 000000000..4b06bfc5e --- /dev/null +++ b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/overwrite_event_holder.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::BCAT { + +IOverwriteEventHolder::IOverwriteEventHolder(Core::System& system_) + : ServiceFramework{system_, "IOverwriteEventHolder"}, service_context{system_, + "IOverwriteEventHolder"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IOverwriteEventHolder::Get>, "Get"}, + }; + // clang-format on + + RegisterHandlers(functions); + overwrite_event = service_context.CreateEvent("IOverwriteEventHolder::OverwriteEvent"); +} + +IOverwriteEventHolder::~IOverwriteEventHolder() = default; + +Result IOverwriteEventHolder::Get(OutCopyHandle out_event) { + LOG_INFO(Service_BCAT, "called"); + + *out_event = &overwrite_event->GetReadableEvent(); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.h b/src/core/hle/service/bcat/news/overwrite_event_holder.h new file mode 100644 index 000000000..4b016b2fe --- /dev/null +++ b/src/core/hle/service/bcat/news/overwrite_event_holder.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +class KReadableEvent; +} // namespace Kernel + +namespace Service::BCAT { + +class IOverwriteEventHolder final : public ServiceFramework { +public: + explicit IOverwriteEventHolder(Core::System& system_); + ~IOverwriteEventHolder() override; + +private: + Result Get(OutCopyHandle out_event); + + Kernel::KEvent* overwrite_event; + KernelHelpers::ServiceContext service_context; +}; + +} // namespace Service::BCAT -- cgit v1.2.3 From 816d03f7d96278c5b3d2604f94901270b10d4167 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Fri, 9 Feb 2024 10:31:35 -0600 Subject: service: bcat: Address review issues --- src/core/CMakeLists.txt | 8 +-- src/core/file_sys/errors.h | 1 + src/core/hle/service/bcat/bcat.cpp | 30 +++++----- src/core/hle/service/bcat/bcat_interface.cpp | 61 --------------------- src/core/hle/service/bcat/bcat_interface.h | 40 -------------- src/core/hle/service/bcat/bcat_result.h | 5 -- src/core/hle/service/bcat/bcat_service.cpp | 31 ++++++----- src/core/hle/service/bcat/bcat_service.h | 6 +- src/core/hle/service/bcat/bcat_types.h | 10 +++- .../bcat/delivery_cache_directory_service.cpp | 23 ++++---- .../bcat/delivery_cache_directory_service.h | 6 +- .../service/bcat/delivery_cache_file_service.cpp | 11 ++-- .../hle/service/bcat/delivery_cache_file_service.h | 2 +- .../bcat/delivery_cache_progress_service.cpp | 4 +- .../bcat/delivery_cache_storage_service.cpp | 16 +++--- .../service/bcat/delivery_cache_storage_service.h | 4 +- .../bcat/news/newly_arrived_event_holder.cpp | 8 ++- .../service/bcat/news/newly_arrived_event_holder.h | 4 +- .../hle/service/bcat/news/news_data_service.cpp | 4 +- src/core/hle/service/bcat/news/news_data_service.h | 4 +- .../service/bcat/news/news_database_service.cpp | 6 +- .../hle/service/bcat/news/news_database_service.h | 6 +- src/core/hle/service/bcat/news/news_interface.cpp | 63 --------------------- src/core/hle/service/bcat/news/news_interface.h | 35 ------------ src/core/hle/service/bcat/news/news_service.cpp | 4 +- src/core/hle/service/bcat/news/news_service.h | 4 +- .../service/bcat/news/overwrite_event_holder.cpp | 8 ++- .../hle/service/bcat/news/overwrite_event_holder.h | 4 +- src/core/hle/service/bcat/news/service_creator.cpp | 64 ++++++++++++++++++++++ src/core/hle/service/bcat/news/service_creator.h | 35 ++++++++++++ src/core/hle/service/bcat/service_creator.cpp | 62 +++++++++++++++++++++ src/core/hle/service/bcat/service_creator.h | 40 ++++++++++++++ src/core/hle/service/service.cpp | 2 +- 33 files changed, 310 insertions(+), 301 deletions(-) delete mode 100644 src/core/hle/service/bcat/bcat_interface.cpp delete mode 100644 src/core/hle/service/bcat/bcat_interface.h delete mode 100644 src/core/hle/service/bcat/news/news_interface.cpp delete mode 100644 src/core/hle/service/bcat/news/news_interface.h create mode 100644 src/core/hle/service/bcat/news/service_creator.cpp create mode 100644 src/core/hle/service/bcat/news/service_creator.h create mode 100644 src/core/hle/service/bcat/service_creator.cpp create mode 100644 src/core/hle/service/bcat/service_creator.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 539e09894..c7157ff4c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -518,16 +518,14 @@ add_library(core STATIC hle/service/bcat/news/news_data_service.h hle/service/bcat/news/news_database_service.cpp hle/service/bcat/news/news_database_service.h - hle/service/bcat/news/news_interface.cpp - hle/service/bcat/news/news_interface.h hle/service/bcat/news/news_service.cpp hle/service/bcat/news/news_service.h hle/service/bcat/news/overwrite_event_holder.cpp hle/service/bcat/news/overwrite_event_holder.h + hle/service/bcat/news/service_creator.cpp + hle/service/bcat/news/service_creator.h hle/service/bcat/bcat.cpp hle/service/bcat/bcat.h - hle/service/bcat/bcat_interface.cpp - hle/service/bcat/bcat_interface.h hle/service/bcat/bcat_result.h hle/service/bcat/bcat_service.cpp hle/service/bcat/bcat_service.h @@ -541,6 +539,8 @@ add_library(core STATIC hle/service/bcat/delivery_cache_progress_service.h hle/service/bcat/delivery_cache_storage_service.cpp hle/service/bcat/delivery_cache_storage_service.h + hle/service/bcat/service_creator.cpp + hle/service/bcat/service_creator.h hle/service/bpc/bpc.cpp hle/service/bpc/bpc.h hle/service/btdrv/btdrv.cpp diff --git a/src/core/file_sys/errors.h b/src/core/file_sys/errors.h index d4e0eb6f4..b22767bf5 100644 --- a/src/core/file_sys/errors.h +++ b/src/core/file_sys/errors.h @@ -91,6 +91,7 @@ constexpr Result ResultWriteNotPermitted{ErrorModule::FS, 6203}; constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 6325}; constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387}; constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388}; +constexpr Result ResultPermissionDenied{ErrorModule::FS, 6400}; constexpr Result ResultBufferAllocationFailed{ErrorModule::FS, 6705}; } // namespace FileSys diff --git a/src/core/hle/service/bcat/bcat.cpp b/src/core/hle/service/bcat/bcat.cpp index 02995ddee..ea8b15998 100644 --- a/src/core/hle/service/bcat/bcat.cpp +++ b/src/core/hle/service/bcat/bcat.cpp @@ -3,8 +3,8 @@ #include "core/hle/service/bcat/backend/backend.h" #include "core/hle/service/bcat/bcat.h" -#include "core/hle/service/bcat/bcat_interface.h" -#include "core/hle/service/bcat/news/news_interface.h" +#include "core/hle/service/bcat/news/service_creator.h" +#include "core/hle/service/bcat/service_creator.h" #include "core/hle/service/server_manager.h" namespace Service::BCAT { @@ -13,24 +13,24 @@ void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("bcat:a", - std::make_shared(system, "bcat:a")); + std::make_shared(system, "bcat:a")); server_manager->RegisterNamedService("bcat:m", - std::make_shared(system, "bcat:m")); + std::make_shared(system, "bcat:m")); server_manager->RegisterNamedService("bcat:u", - std::make_shared(system, "bcat:u")); + std::make_shared(system, "bcat:u")); server_manager->RegisterNamedService("bcat:s", - std::make_shared(system, "bcat:s")); + std::make_shared(system, "bcat:s")); server_manager->RegisterNamedService( - "news:a", std::make_shared(system, 0xffffffff, "news:a")); - server_manager->RegisterNamedService("news:p", - std::make_shared(system, 0x1, "news:p")); - server_manager->RegisterNamedService("news:c", - std::make_shared(system, 0x2, "news:c")); - server_manager->RegisterNamedService("news:v", - std::make_shared(system, 0x4, "news:v")); - server_manager->RegisterNamedService("news:m", - std::make_shared(system, 0xd, "news:m")); + "news:a", std::make_shared(system, 0xffffffff, "news:a")); + server_manager->RegisterNamedService( + "news:p", std::make_shared(system, 0x1, "news:p")); + server_manager->RegisterNamedService( + "news:c", std::make_shared(system, 0x2, "news:c")); + server_manager->RegisterNamedService( + "news:v", std::make_shared(system, 0x4, "news:v")); + server_manager->RegisterNamedService( + "news:m", std::make_shared(system, 0xd, "news:m")); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/bcat/bcat_interface.cpp b/src/core/hle/service/bcat/bcat_interface.cpp deleted file mode 100644 index 2d9a0efcc..000000000 --- a/src/core/hle/service/bcat/bcat_interface.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/bcat/bcat_interface.h" -#include "core/hle/service/bcat/bcat_service.h" -#include "core/hle/service/bcat/delivery_cache_storage_service.h" -#include "core/hle/service/cmif_serialization.h" -#include "core/hle/service/filesystem/filesystem.h" - -namespace Service::BCAT { - -std::unique_ptr CreateBackendFromSettings([[maybe_unused]] Core::System& system, - DirectoryGetter getter) { - return std::make_unique(std::move(getter)); -} - -BcatInterface::BcatInterface(Core::System& system_, const char* name_) - : ServiceFramework{system_, name_}, fsc{system.GetFileSystemController()} { - // clang-format off - static const FunctionInfo functions[] = { - {0, C<&BcatInterface::CreateBcatService>, "CreateBcatService"}, - {1, C<&BcatInterface::CreateDeliveryCacheStorageService>, "CreateDeliveryCacheStorageService"}, - {2, C<&BcatInterface::CreateDeliveryCacheStorageServiceWithApplicationId>, "CreateDeliveryCacheStorageServiceWithApplicationId"}, - {3, nullptr, "CreateDeliveryCacheProgressService"}, - {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"}, - }; - // clang-format on - - RegisterHandlers(functions); - - backend = - CreateBackendFromSettings(system_, [this](u64 tid) { return fsc.GetBCATDirectory(tid); }); -} - -BcatInterface::~BcatInterface() = default; - -Result BcatInterface::CreateBcatService(OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - *out_interface = std::make_shared(system, *backend); - R_SUCCEED(); -} - -Result BcatInterface::CreateDeliveryCacheStorageService( - OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - - const auto title_id = system.GetApplicationProcessProgramID(); - *out_interface = - std::make_shared(system, fsc.GetBCATDirectory(title_id)); - R_SUCCEED(); -} - -Result BcatInterface::CreateDeliveryCacheStorageServiceWithApplicationId( - u64 title_id, OutInterface out_interface) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); - *out_interface = - std::make_shared(system, fsc.GetBCATDirectory(title_id)); - R_SUCCEED(); -} - -} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_interface.h b/src/core/hle/service/bcat/bcat_interface.h deleted file mode 100644 index 9282b57bb..000000000 --- a/src/core/hle/service/bcat/bcat_interface.h +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "core/hle/service/cmif_types.h" -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service::FileSystem { -class FileSystemController; -} - -namespace Service::BCAT { -class BcatBackend; -class IBcatService; -class IDeliveryCacheStorageService; - -class BcatInterface final : public ServiceFramework { -public: - explicit BcatInterface(Core::System& system_, const char* name_); - ~BcatInterface() override; - -private: - Result CreateBcatService(OutInterface out_interface); - - Result CreateDeliveryCacheStorageService( - OutInterface out_interface); - - Result CreateDeliveryCacheStorageServiceWithApplicationId( - u64 title_id, OutInterface out_interface); - - std::unique_ptr backend; - Service::FileSystem::FileSystemController& fsc; -}; - -} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_result.h b/src/core/hle/service/bcat/bcat_result.h index d711924b1..edf8a6564 100644 --- a/src/core/hle/service/bcat/bcat_result.h +++ b/src/core/hle/service/bcat/bcat_result.h @@ -12,9 +12,4 @@ constexpr Result ResultFailedOpenEntity{ErrorModule::BCAT, 2}; constexpr Result ResultEntityAlreadyOpen{ErrorModule::BCAT, 6}; constexpr Result ResultNoOpenEntry{ErrorModule::BCAT, 7}; -// The command to clear the delivery cache just calls fs IFileSystem DeleteFile on all of the -// files and if any of them have a non-zero result it just forwards that result. This is the FS -// error code for permission denied, which is the closest approximation of this scenario. -constexpr Result ResultFailedClearCache{ErrorModule::FS, 6400}; - } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_service.cpp b/src/core/hle/service/bcat/bcat_service.cpp index 2eacec3ae..63b1072d2 100644 --- a/src/core/hle/service/bcat/bcat_service.cpp +++ b/src/core/hle/service/bcat/bcat_service.cpp @@ -4,6 +4,7 @@ #include "common/hex_util.h" #include "common/string_util.h" #include "core/core.h" +#include "core/file_sys/errors.h" #include "core/hle/service/bcat/backend/backend.h" #include "core/hle/service/bcat/bcat_result.h" #include "core/hle/service/bcat/bcat_service.h" @@ -14,7 +15,7 @@ namespace Service::BCAT { -u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) { +static u64 GetCurrentBuildID(const Core::System::CurrentBuildProcessID& id) { u64 out{}; std::memcpy(&out, id.data(), sizeof(u64)); return out; @@ -28,8 +29,8 @@ IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_) }} { // clang-format off static const FunctionInfo functions[] = { - {10100, C<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"}, - {10101, C<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"}, + {10100, D<&IBcatService::RequestSyncDeliveryCache>, "RequestSyncDeliveryCache"}, + {10101, D<&IBcatService::RequestSyncDeliveryCacheWithDirectoryName>, "RequestSyncDeliveryCacheWithDirectoryName"}, {10200, nullptr, "CancelSyncDeliveryCacheRequest"}, {20100, nullptr, "RequestSyncDeliveryCacheWithApplicationId"}, {20101, nullptr, "RequestSyncDeliveryCacheWithApplicationIdAndDirectoryName"}, @@ -38,7 +39,7 @@ IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_) {20400, nullptr, "RegisterSystemApplicationDeliveryTask"}, {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"}, {20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"}, - {30100, C<&IBcatService::SetPassphrase>, "SetPassphrase"}, + {30100, D<&IBcatService::SetPassphrase>, "SetPassphrase"}, {30101, nullptr, "Unknown30101"}, {30102, nullptr, "Unknown30102"}, {30200, nullptr, "RegisterBackgroundDeliveryTask"}, @@ -46,11 +47,11 @@ IBcatService::IBcatService(Core::System& system_, BcatBackend& backend_) {30202, nullptr, "BlockDeliveryTask"}, {30203, nullptr, "UnblockDeliveryTask"}, {30210, nullptr, "SetDeliveryTaskTimer"}, - {30300, C<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"}, + {30300, D<&IBcatService::RegisterSystemApplicationDeliveryTasks>, "RegisterSystemApplicationDeliveryTasks"}, {90100, nullptr, "EnumerateBackgroundDeliveryTask"}, {90101, nullptr, "Unknown90101"}, {90200, nullptr, "GetDeliveryList"}, - {90201, C<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"}, + {90201, D<&IBcatService::ClearDeliveryCacheStorage>, "ClearDeliveryCacheStorage"}, {90202, nullptr, "ClearDeliveryTaskSubscriptionStatus"}, {90300, nullptr, "GetPushNotificationLog"}, {90301, nullptr, "Unknown90301"}, @@ -76,7 +77,7 @@ Result IBcatService::RequestSyncDeliveryCache( } Result IBcatService::RequestSyncDeliveryCacheWithDirectoryName( - DirectoryName name_raw, OutInterface out_interface) { + const DirectoryName& name_raw, OutInterface out_interface) { const auto name = Common::StringFromFixedZeroTerminatedBuffer(name_raw.data(), name_raw.size()); LOG_DEBUG(Service_BCAT, "called, name={}", name); @@ -91,19 +92,19 @@ Result IBcatService::RequestSyncDeliveryCacheWithDirectoryName( R_SUCCEED(); } -Result IBcatService::SetPassphrase(u64 title_id, +Result IBcatService::SetPassphrase(u64 application_id, InBuffer passphrase_buffer) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, + LOG_DEBUG(Service_BCAT, "called, application_id={:016X}, passphrase={}", application_id, Common::HexToString(passphrase_buffer)); - R_UNLESS(title_id != 0, ResultInvalidArgument); + R_UNLESS(application_id != 0, ResultInvalidArgument); R_UNLESS(passphrase_buffer.size() <= 0x40, ResultInvalidArgument); Passphrase passphrase{}; std::memcpy(passphrase.data(), passphrase_buffer.data(), std::min(passphrase.size(), passphrase_buffer.size())); - backend.SetPassphrase(title_id, passphrase); + backend.SetPassphrase(application_id, passphrase); R_SUCCEED(); } @@ -112,11 +113,11 @@ Result IBcatService::RegisterSystemApplicationDeliveryTasks() { R_SUCCEED(); } -Result IBcatService::ClearDeliveryCacheStorage(u64 title_id) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); +Result IBcatService::ClearDeliveryCacheStorage(u64 application_id) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", application_id); - R_UNLESS(title_id != 0, ResultInvalidArgument); - R_UNLESS(backend.Clear(title_id), ResultFailedClearCache); + R_UNLESS(application_id != 0, ResultInvalidArgument); + R_UNLESS(backend.Clear(application_id), FileSys::ResultPermissionDenied); R_SUCCEED(); } diff --git a/src/core/hle/service/bcat/bcat_service.h b/src/core/hle/service/bcat/bcat_service.h index 3e1ed98c3..dda5a2d5f 100644 --- a/src/core/hle/service/bcat/bcat_service.h +++ b/src/core/hle/service/bcat/bcat_service.h @@ -26,13 +26,13 @@ private: Result RequestSyncDeliveryCache(OutInterface out_interface); Result RequestSyncDeliveryCacheWithDirectoryName( - DirectoryName name, OutInterface out_interface); + const DirectoryName& name, OutInterface out_interface); - Result SetPassphrase(u64 title_id, InBuffer passphrase_buffer); + Result SetPassphrase(u64 application_id, InBuffer passphrase_buffer); Result RegisterSystemApplicationDeliveryTasks(); - Result ClearDeliveryCacheStorage(u64 title_id); + Result ClearDeliveryCacheStorage(u64 application_id); private: ProgressServiceBackend& GetProgressBackend(SyncType type); diff --git a/src/core/hle/service/bcat/bcat_types.h b/src/core/hle/service/bcat/bcat_types.h index a56f9248f..b35dab7c5 100644 --- a/src/core/hle/service/bcat/bcat_types.h +++ b/src/core/hle/service/bcat/bcat_types.h @@ -3,9 +3,13 @@ #pragma once +#include +#include + #include "common/common_funcs.h" #include "common/common_types.h" #include "core/file_sys/vfs/vfs_types.h" +#include "core/hle/result.h" namespace Service::BCAT { @@ -44,17 +48,19 @@ struct TitleIDVersion { struct DeliveryCacheProgressImpl { DeliveryCacheProgressStatus status; - Result result = ResultSuccess; + Result result; DirectoryName current_directory; FileName current_file; s64 current_downloaded_bytes; ///< Bytes downloaded on current file. s64 current_total_bytes; ///< Bytes total on current file. s64 total_downloaded_bytes; ///< Bytes downloaded on overall download. s64 total_bytes; ///< Bytes total on overall download. - INSERT_PADDING_BYTES( + INSERT_PADDING_BYTES_NOINIT( 0x198); ///< Appears to be unused in official code, possibly reserved for future use. }; static_assert(sizeof(DeliveryCacheProgressImpl) == 0x200, "DeliveryCacheProgressImpl has incorrect size."); +static_assert(std::is_trivial_v, + "DeliveryCacheProgressImpl type must be trivially copyable."); } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.cpp b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp index 8bda1168a..01f08a2fc 100644 --- a/src/core/hle/service/bcat/delivery_cache_directory_service.cpp +++ b/src/core/hle/service/bcat/delivery_cache_directory_service.cpp @@ -12,7 +12,7 @@ namespace Service::BCAT { // The digest is only used to determine if a file is unique compared to others of the same name. // Since the algorithm isn't ever checked in game, MD5 is safe. -BcatDigest DigestFile(const FileSys::VirtualFile& file) { +static BcatDigest DigestFile(const FileSys::VirtualFile& file) { BcatDigest out{}; const auto bytes = file->ReadAllBytes(); mbedtls_md5_ret(bytes.data(), bytes.size(), out.data()); @@ -24,9 +24,9 @@ IDeliveryCacheDirectoryService::IDeliveryCacheDirectoryService(Core::System& sys : ServiceFramework{system_, "IDeliveryCacheDirectoryService"}, root(std::move(root_)) { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IDeliveryCacheDirectoryService::Open>, "Open"}, - {1, C<&IDeliveryCacheDirectoryService::Read>, "Read"}, - {2, C<&IDeliveryCacheDirectoryService::GetCount>, "GetCount"}, + {0, D<&IDeliveryCacheDirectoryService::Open>, "Open"}, + {1, D<&IDeliveryCacheDirectoryService::Read>, "Read"}, + {2, D<&IDeliveryCacheDirectoryService::GetCount>, "GetCount"}, }; // clang-format on @@ -35,13 +35,13 @@ IDeliveryCacheDirectoryService::IDeliveryCacheDirectoryService(Core::System& sys IDeliveryCacheDirectoryService::~IDeliveryCacheDirectoryService() = default; -Result IDeliveryCacheDirectoryService::Open(DirectoryName dir_name_raw) { +Result IDeliveryCacheDirectoryService::Open(const DirectoryName& dir_name_raw) { const auto dir_name = Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size()); LOG_DEBUG(Service_BCAT, "called, dir_name={}", dir_name); - // R_TRY(VerifyNameValidDir(dir_name_raw)); + R_TRY(VerifyNameValidDir(dir_name_raw)); R_UNLESS(current_dir == nullptr, ResultEntityAlreadyOpen); const auto dir = root->GetSubdirectory(dir_name); @@ -51,15 +51,14 @@ Result IDeliveryCacheDirectoryService::Open(DirectoryName dir_name_raw) { } Result IDeliveryCacheDirectoryService::Read( - Out out_buffer_size, - OutArray out_buffer) { + Out out_count, OutArray out_buffer) { LOG_DEBUG(Service_BCAT, "called, write_size={:016X}", out_buffer.size()); R_UNLESS(current_dir != nullptr, ResultNoOpenEntry); const auto files = current_dir->GetFiles(); - *out_buffer_size = static_cast(std::min(files.size(), out_buffer.size())); - std::transform(files.begin(), files.begin() + *out_buffer_size, out_buffer.begin(), + *out_count = static_cast(std::min(files.size(), out_buffer.size())); + std::transform(files.begin(), files.begin() + *out_count, out_buffer.begin(), [](const auto& file) { FileName name{}; std::memcpy(name.data(), file->GetName().data(), @@ -69,12 +68,12 @@ Result IDeliveryCacheDirectoryService::Read( R_SUCCEED(); } -Result IDeliveryCacheDirectoryService::GetCount(Out out_count) { +Result IDeliveryCacheDirectoryService::GetCount(Out out_count) { LOG_DEBUG(Service_BCAT, "called"); R_UNLESS(current_dir != nullptr, ResultNoOpenEntry); - *out_count = static_cast(current_dir->GetFiles().size()); + *out_count = static_cast(current_dir->GetFiles().size()); R_SUCCEED(); } diff --git a/src/core/hle/service/bcat/delivery_cache_directory_service.h b/src/core/hle/service/bcat/delivery_cache_directory_service.h index f544d0947..b902c6495 100644 --- a/src/core/hle/service/bcat/delivery_cache_directory_service.h +++ b/src/core/hle/service/bcat/delivery_cache_directory_service.h @@ -21,10 +21,10 @@ public: ~IDeliveryCacheDirectoryService() override; private: - Result Open(DirectoryName dir_name_raw); - Result Read(Out out_buffer_size, + Result Open(const DirectoryName& dir_name_raw); + Result Read(Out out_count, OutArray out_buffer); - Result GetCount(Out out_count); + Result GetCount(Out out_count); FileSys::VirtualDir root; FileSys::VirtualDir current_dir; diff --git a/src/core/hle/service/bcat/delivery_cache_file_service.cpp b/src/core/hle/service/bcat/delivery_cache_file_service.cpp index c91efd47e..b75fac4bf 100644 --- a/src/core/hle/service/bcat/delivery_cache_file_service.cpp +++ b/src/core/hle/service/bcat/delivery_cache_file_service.cpp @@ -14,10 +14,10 @@ IDeliveryCacheFileService::IDeliveryCacheFileService(Core::System& system_, : ServiceFramework{system_, "IDeliveryCacheFileService"}, root(std::move(root_)) { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IDeliveryCacheFileService::Open>, "Open"}, - {1, C<&IDeliveryCacheFileService::Read>, "Read"}, - {2, C<&IDeliveryCacheFileService::GetSize>, "GetSize"}, - {3, C<&IDeliveryCacheFileService::GetDigest>, "GetDigest"}, + {0, D<&IDeliveryCacheFileService::Open>, "Open"}, + {1, D<&IDeliveryCacheFileService::Read>, "Read"}, + {2, D<&IDeliveryCacheFileService::GetSize>, "GetSize"}, + {3, D<&IDeliveryCacheFileService::GetDigest>, "GetDigest"}, }; // clang-format on @@ -26,7 +26,8 @@ IDeliveryCacheFileService::IDeliveryCacheFileService(Core::System& system_, IDeliveryCacheFileService::~IDeliveryCacheFileService() = default; -Result IDeliveryCacheFileService::Open(DirectoryName dir_name_raw, FileName file_name_raw) { +Result IDeliveryCacheFileService::Open(const DirectoryName& dir_name_raw, + const FileName& file_name_raw) { const auto dir_name = Common::StringFromFixedZeroTerminatedBuffer(dir_name_raw.data(), dir_name_raw.size()); const auto file_name = diff --git a/src/core/hle/service/bcat/delivery_cache_file_service.h b/src/core/hle/service/bcat/delivery_cache_file_service.h index 7583b4d1d..e1012e687 100644 --- a/src/core/hle/service/bcat/delivery_cache_file_service.h +++ b/src/core/hle/service/bcat/delivery_cache_file_service.h @@ -20,7 +20,7 @@ public: ~IDeliveryCacheFileService() override; private: - Result Open(DirectoryName dir_name_raw, FileName file_name_raw); + Result Open(const DirectoryName& dir_name_raw, const FileName& file_name_raw); Result Read(Out out_buffer_size, u64 offset, OutBuffer out_buffer); Result GetSize(Out out_size); diff --git a/src/core/hle/service/bcat/delivery_cache_progress_service.cpp b/src/core/hle/service/bcat/delivery_cache_progress_service.cpp index 94d341f7e..79e7e0d95 100644 --- a/src/core/hle/service/bcat/delivery_cache_progress_service.cpp +++ b/src/core/hle/service/bcat/delivery_cache_progress_service.cpp @@ -13,8 +13,8 @@ IDeliveryCacheProgressService::IDeliveryCacheProgressService(Core::System& syste : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{event_}, impl{impl_} { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IDeliveryCacheProgressService::GetEvent>, "Get"}, - {0, C<&IDeliveryCacheProgressService::GetImpl>, "Get"}, + {0, D<&IDeliveryCacheProgressService::GetEvent>, "Get"}, + {1, D<&IDeliveryCacheProgressService::GetImpl>, "Get"}, }; // clang-format on diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.cpp b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp index 5d03df1e7..4c79d71f4 100644 --- a/src/core/hle/service/bcat/delivery_cache_storage_service.cpp +++ b/src/core/hle/service/bcat/delivery_cache_storage_service.cpp @@ -14,9 +14,9 @@ IDeliveryCacheStorageService::IDeliveryCacheStorageService(Core::System& system_ : ServiceFramework{system_, "IDeliveryCacheStorageService"}, root(std::move(root_)) { // clang-format off static const FunctionInfo functions[] = { - {0, C<&IDeliveryCacheStorageService::CreateFileService>, "CreateFileService"}, - {1, C<&IDeliveryCacheStorageService::CreateDirectoryService>, "CreateDirectoryService"}, - {2, C<&IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory>, "EnumerateDeliveryCacheDirectory"}, + {0, D<&IDeliveryCacheStorageService::CreateFileService>, "CreateFileService"}, + {1, D<&IDeliveryCacheStorageService::CreateDirectoryService>, "CreateDirectoryService"}, + {10, D<&IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory>, "EnumerateDeliveryCacheDirectory"}, }; // clang-format on @@ -42,15 +42,15 @@ Result IDeliveryCacheStorageService::CreateDirectoryService( } Result IDeliveryCacheStorageService::EnumerateDeliveryCacheDirectory( - Out out_directories_size, + Out out_directory_count, OutArray out_directories) { LOG_DEBUG(Service_BCAT, "called, size={:016X}", out_directories.size()); - *out_directories_size = - static_cast(std::min(out_directories.size(), entries.size() - next_read_index)); + *out_directory_count = + static_cast(std::min(out_directories.size(), entries.size() - next_read_index)); memcpy(out_directories.data(), entries.data() + next_read_index, - *out_directories_size * sizeof(DirectoryName)); - next_read_index += *out_directories_size; + *out_directory_count * sizeof(DirectoryName)); + next_read_index += *out_directory_count; R_SUCCEED(); } diff --git a/src/core/hle/service/bcat/delivery_cache_storage_service.h b/src/core/hle/service/bcat/delivery_cache_storage_service.h index 1e86d3dbf..3b8dfb1a3 100644 --- a/src/core/hle/service/bcat/delivery_cache_storage_service.h +++ b/src/core/hle/service/bcat/delivery_cache_storage_service.h @@ -25,12 +25,12 @@ private: Result CreateFileService(OutInterface out_interface); Result CreateDirectoryService(OutInterface out_interface); Result EnumerateDeliveryCacheDirectory( - Out out_directories_size, + Out out_directory_count, OutArray out_directories); FileSys::VirtualDir root; std::vector entries; - u64 next_read_index = 0; + std::size_t next_read_index = 0; }; } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp index b3f9e4683..5be167fce 100644 --- a/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp +++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.cpp @@ -4,7 +4,7 @@ #include "core/hle/service/bcat/news/newly_arrived_event_holder.h" #include "core/hle/service/cmif_serialization.h" -namespace Service::BCAT { +namespace Service::News { INewlyArrivedEventHolder::INewlyArrivedEventHolder(Core::System& system_) : ServiceFramework{system_, "INewlyArrivedEventHolder"}, service_context{ @@ -20,7 +20,9 @@ INewlyArrivedEventHolder::INewlyArrivedEventHolder(Core::System& system_) arrived_event = service_context.CreateEvent("INewlyArrivedEventHolder::ArrivedEvent"); } -INewlyArrivedEventHolder::~INewlyArrivedEventHolder() = default; +INewlyArrivedEventHolder::~INewlyArrivedEventHolder() { + service_context.CloseEvent(arrived_event); +} Result INewlyArrivedEventHolder::Get(OutCopyHandle out_event) { LOG_INFO(Service_BCAT, "called"); @@ -29,4 +31,4 @@ Result INewlyArrivedEventHolder::Get(OutCopyHandle out_e R_SUCCEED(); } -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/newly_arrived_event_holder.h b/src/core/hle/service/bcat/news/newly_arrived_event_holder.h index af19d81a7..6cc9ae099 100644 --- a/src/core/hle/service/bcat/news/newly_arrived_event_holder.h +++ b/src/core/hle/service/bcat/news/newly_arrived_event_holder.h @@ -16,7 +16,7 @@ class KEvent; class KReadableEvent; } // namespace Kernel -namespace Service::BCAT { +namespace Service::News { class INewlyArrivedEventHolder final : public ServiceFramework { public: @@ -30,4 +30,4 @@ private: KernelHelpers::ServiceContext service_context; }; -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_data_service.cpp b/src/core/hle/service/bcat/news/news_data_service.cpp index eba2e6064..08103c9c3 100644 --- a/src/core/hle/service/bcat/news/news_data_service.cpp +++ b/src/core/hle/service/bcat/news/news_data_service.cpp @@ -3,7 +3,7 @@ #include "core/hle/service/bcat/news/news_data_service.h" -namespace Service::BCAT { +namespace Service::News { INewsDataService::INewsDataService(Core::System& system_) : ServiceFramework{system_, "INewsDataService"} { @@ -22,4 +22,4 @@ INewsDataService::INewsDataService(Core::System& system_) INewsDataService::~INewsDataService() = default; -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_data_service.h b/src/core/hle/service/bcat/news/news_data_service.h index 441e0ea8e..12082ada4 100644 --- a/src/core/hle/service/bcat/news/news_data_service.h +++ b/src/core/hle/service/bcat/news/news_data_service.h @@ -9,7 +9,7 @@ namespace Core { class System; } -namespace Service::BCAT { +namespace Service::News { class INewsDataService final : public ServiceFramework { public: @@ -17,4 +17,4 @@ public: ~INewsDataService() override; }; -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_database_service.cpp b/src/core/hle/service/bcat/news/news_database_service.cpp index 3b4b33901..18109f9b0 100644 --- a/src/core/hle/service/bcat/news/news_database_service.cpp +++ b/src/core/hle/service/bcat/news/news_database_service.cpp @@ -4,7 +4,7 @@ #include "core/hle/service/bcat/news/news_database_service.h" #include "core/hle/service/cmif_serialization.h" -namespace Service::BCAT { +namespace Service::News { INewsDatabaseService::INewsDatabaseService(Core::System& system_) : ServiceFramework{system_, "INewsDatabaseService"} { @@ -25,11 +25,11 @@ INewsDatabaseService::INewsDatabaseService(Core::System& system_) INewsDatabaseService::~INewsDatabaseService() = default; -Result INewsDatabaseService::Count(Out out_count, +Result INewsDatabaseService::Count(Out out_count, InBuffer buffer_data) { LOG_WARNING(Service_BCAT, "(STUBBED) called, buffer_size={}", buffer_data.size()); *out_count = 0; R_SUCCEED(); } -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_database_service.h b/src/core/hle/service/bcat/news/news_database_service.h index dd09a1662..f5916634b 100644 --- a/src/core/hle/service/bcat/news/news_database_service.h +++ b/src/core/hle/service/bcat/news/news_database_service.h @@ -10,7 +10,7 @@ namespace Core { class System; } -namespace Service::BCAT { +namespace Service::News { class INewsDatabaseService final : public ServiceFramework { public: @@ -18,7 +18,7 @@ public: ~INewsDatabaseService() override; private: - Result Count(Out out_count, InBuffer buffer_data); + Result Count(Out out_count, InBuffer buffer_data); }; -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_interface.cpp b/src/core/hle/service/bcat/news/news_interface.cpp deleted file mode 100644 index 0eaef2ddc..000000000 --- a/src/core/hle/service/bcat/news/news_interface.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/bcat/news/newly_arrived_event_holder.h" -#include "core/hle/service/bcat/news/news_data_service.h" -#include "core/hle/service/bcat/news/news_database_service.h" -#include "core/hle/service/bcat/news/news_interface.h" -#include "core/hle/service/bcat/news/news_service.h" -#include "core/hle/service/bcat/news/overwrite_event_holder.h" -#include "core/hle/service/cmif_serialization.h" - -namespace Service::BCAT { - -NewsInterface::NewsInterface(Core::System& system_, u32 permissions_, const char* name_) - : ServiceFramework{system_, name_}, permissions{permissions_} { - // clang-format off - static const FunctionInfo functions[] = { - {0, C<&NewsInterface::CreateNewsService>, "CreateNewsService"}, - {1, C<&NewsInterface::CreateNewlyArrivedEventHolder>, "CreateNewlyArrivedEventHolder"}, - {2, C<&NewsInterface::CreateNewsDataService>, "CreateNewsDataService"}, - {3, C<&NewsInterface::CreateNewsDatabaseService>, "CreateNewsDatabaseService"}, - {4, C<&NewsInterface::CreateOverwriteEventHolder>, "CreateOverwriteEventHolder"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -NewsInterface::~NewsInterface() = default; - -Result NewsInterface::CreateNewsService(OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - *out_interface = std::make_shared(system); - R_SUCCEED(); -} - -Result NewsInterface::CreateNewlyArrivedEventHolder( - OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - *out_interface = std::make_shared(system); - R_SUCCEED(); -} - -Result NewsInterface::CreateNewsDataService(OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - *out_interface = std::make_shared(system); - R_SUCCEED(); -} - -Result NewsInterface::CreateNewsDatabaseService(OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - *out_interface = std::make_shared(system); - R_SUCCEED(); -} - -Result NewsInterface::CreateOverwriteEventHolder( - OutInterface out_interface) { - LOG_INFO(Service_BCAT, "called"); - *out_interface = std::make_shared(system); - R_SUCCEED(); -} - -} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_interface.h b/src/core/hle/service/bcat/news/news_interface.h deleted file mode 100644 index d95edba3d..000000000 --- a/src/core/hle/service/bcat/news/news_interface.h +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "core/hle/service/cmif_types.h" -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service::BCAT { -class INewsService; -class INewlyArrivedEventHolder; -class INewsDataService; -class INewsDatabaseService; -class IOverwriteEventHolder; - -class NewsInterface final : public ServiceFramework { -public: - explicit NewsInterface(Core::System& system_, u32 permissions_, const char* name_); - ~NewsInterface() override; - -private: - Result CreateNewsService(OutInterface out_interface); - Result CreateNewlyArrivedEventHolder(OutInterface out_interface); - Result CreateNewsDataService(OutInterface out_interface); - Result CreateNewsDatabaseService(OutInterface out_interface); - Result CreateOverwriteEventHolder(OutInterface out_interface); - - u32 permissions; -}; - -} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/news/news_service.cpp b/src/core/hle/service/bcat/news/news_service.cpp index 372937351..e19cea7b5 100644 --- a/src/core/hle/service/bcat/news/news_service.cpp +++ b/src/core/hle/service/bcat/news/news_service.cpp @@ -4,7 +4,7 @@ #include "core/hle/service/bcat/news/news_service.h" #include "core/hle/service/cmif_serialization.h" -namespace Service::BCAT { +namespace Service::News { INewsService::INewsService(Core::System& system_) : ServiceFramework{system_, "INewsService"} { // clang-format off @@ -43,4 +43,4 @@ Result INewsService::GetSubscriptionStatus(Out out_status, R_SUCCEED(); } -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/news_service.h b/src/core/hle/service/bcat/news/news_service.h index bb2e49848..8d06be9d6 100644 --- a/src/core/hle/service/bcat/news/news_service.h +++ b/src/core/hle/service/bcat/news/news_service.h @@ -10,7 +10,7 @@ namespace Core { class System; } -namespace Service::BCAT { +namespace Service::News { class INewsService final : public ServiceFramework { public: @@ -21,4 +21,4 @@ private: Result GetSubscriptionStatus(Out out_status, InBuffer buffer_data); }; -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.cpp b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp index 4b06bfc5e..c32a5ca8f 100644 --- a/src/core/hle/service/bcat/news/overwrite_event_holder.cpp +++ b/src/core/hle/service/bcat/news/overwrite_event_holder.cpp @@ -4,7 +4,7 @@ #include "core/hle/service/bcat/news/overwrite_event_holder.h" #include "core/hle/service/cmif_serialization.h" -namespace Service::BCAT { +namespace Service::News { IOverwriteEventHolder::IOverwriteEventHolder(Core::System& system_) : ServiceFramework{system_, "IOverwriteEventHolder"}, service_context{system_, @@ -19,7 +19,9 @@ IOverwriteEventHolder::IOverwriteEventHolder(Core::System& system_) overwrite_event = service_context.CreateEvent("IOverwriteEventHolder::OverwriteEvent"); } -IOverwriteEventHolder::~IOverwriteEventHolder() = default; +IOverwriteEventHolder::~IOverwriteEventHolder() { + service_context.CloseEvent(overwrite_event); +} Result IOverwriteEventHolder::Get(OutCopyHandle out_event) { LOG_INFO(Service_BCAT, "called"); @@ -28,4 +30,4 @@ Result IOverwriteEventHolder::Get(OutCopyHandle out_even R_SUCCEED(); } -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/overwrite_event_holder.h b/src/core/hle/service/bcat/news/overwrite_event_holder.h index 4b016b2fe..cdc87d782 100644 --- a/src/core/hle/service/bcat/news/overwrite_event_holder.h +++ b/src/core/hle/service/bcat/news/overwrite_event_holder.h @@ -16,7 +16,7 @@ class KEvent; class KReadableEvent; } // namespace Kernel -namespace Service::BCAT { +namespace Service::News { class IOverwriteEventHolder final : public ServiceFramework { public: @@ -30,4 +30,4 @@ private: KernelHelpers::ServiceContext service_context; }; -} // namespace Service::BCAT +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/service_creator.cpp b/src/core/hle/service/bcat/news/service_creator.cpp new file mode 100644 index 000000000..d5ba5dff7 --- /dev/null +++ b/src/core/hle/service/bcat/news/service_creator.cpp @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/hle/service/bcat/news/newly_arrived_event_holder.h" +#include "core/hle/service/bcat/news/news_data_service.h" +#include "core/hle/service/bcat/news/news_database_service.h" +#include "core/hle/service/bcat/news/news_service.h" +#include "core/hle/service/bcat/news/overwrite_event_holder.h" +#include "core/hle/service/bcat/news/service_creator.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::News { + +IServiceCreator::IServiceCreator(Core::System& system_, u32 permissions_, const char* name_) + : ServiceFramework{system_, name_}, permissions{permissions_} { + // clang-format off + static const FunctionInfo functions[] = { + {0, C<&IServiceCreator::CreateNewsService>, "CreateNewsService"}, + {1, C<&IServiceCreator::CreateNewlyArrivedEventHolder>, "CreateNewlyArrivedEventHolder"}, + {2, C<&IServiceCreator::CreateNewsDataService>, "CreateNewsDataService"}, + {3, C<&IServiceCreator::CreateNewsDatabaseService>, "CreateNewsDatabaseService"}, + {4, C<&IServiceCreator::CreateOverwriteEventHolder>, "CreateOverwriteEventHolder"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IServiceCreator::~IServiceCreator() = default; + +Result IServiceCreator::CreateNewsService(OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result IServiceCreator::CreateNewlyArrivedEventHolder( + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result IServiceCreator::CreateNewsDataService(OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result IServiceCreator::CreateNewsDatabaseService( + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +Result IServiceCreator::CreateOverwriteEventHolder( + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called"); + *out_interface = std::make_shared(system); + R_SUCCEED(); +} + +} // namespace Service::News diff --git a/src/core/hle/service/bcat/news/service_creator.h b/src/core/hle/service/bcat/news/service_creator.h new file mode 100644 index 000000000..5a62e7c1a --- /dev/null +++ b/src/core/hle/service/bcat/news/service_creator.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::News { +class INewsService; +class INewlyArrivedEventHolder; +class INewsDataService; +class INewsDatabaseService; +class IOverwriteEventHolder; + +class IServiceCreator final : public ServiceFramework { +public: + explicit IServiceCreator(Core::System& system_, u32 permissions_, const char* name_); + ~IServiceCreator() override; + +private: + Result CreateNewsService(OutInterface out_interface); + Result CreateNewlyArrivedEventHolder(OutInterface out_interface); + Result CreateNewsDataService(OutInterface out_interface); + Result CreateNewsDatabaseService(OutInterface out_interface); + Result CreateOverwriteEventHolder(OutInterface out_interface); + + u32 permissions; +}; + +} // namespace Service::News diff --git a/src/core/hle/service/bcat/service_creator.cpp b/src/core/hle/service/bcat/service_creator.cpp new file mode 100644 index 000000000..ca339e5a6 --- /dev/null +++ b/src/core/hle/service/bcat/service_creator.cpp @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/bcat/bcat_service.h" +#include "core/hle/service/bcat/delivery_cache_storage_service.h" +#include "core/hle/service/bcat/service_creator.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/filesystem/filesystem.h" + +namespace Service::BCAT { + +std::unique_ptr CreateBackendFromSettings([[maybe_unused]] Core::System& system, + DirectoryGetter getter) { + return std::make_unique(std::move(getter)); +} + +IServiceCreator::IServiceCreator(Core::System& system_, const char* name_) + : ServiceFramework{system_, name_}, fsc{system.GetFileSystemController()} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&IServiceCreator::CreateBcatService>, "CreateBcatService"}, + {1, D<&IServiceCreator::CreateDeliveryCacheStorageService>, "CreateDeliveryCacheStorageService"}, + {2, D<&IServiceCreator::CreateDeliveryCacheStorageServiceWithApplicationId>, "CreateDeliveryCacheStorageServiceWithApplicationId"}, + {3, nullptr, "CreateDeliveryCacheProgressService"}, + {4, nullptr, "CreateDeliveryCacheProgressServiceWithApplicationId"}, + }; + // clang-format on + + RegisterHandlers(functions); + + backend = + CreateBackendFromSettings(system_, [this](u64 tid) { return fsc.GetBCATDirectory(tid); }); +} + +IServiceCreator::~IServiceCreator() = default; + +Result IServiceCreator::CreateBcatService(ClientProcessId process_id, + OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called, process_id={}", process_id.pid); + *out_interface = std::make_shared(system, *backend); + R_SUCCEED(); +} + +Result IServiceCreator::CreateDeliveryCacheStorageService( + ClientProcessId process_id, OutInterface out_interface) { + LOG_INFO(Service_BCAT, "called, process_id={}", process_id.pid); + + const auto title_id = system.GetApplicationProcessProgramID(); + *out_interface = + std::make_shared(system, fsc.GetBCATDirectory(title_id)); + R_SUCCEED(); +} + +Result IServiceCreator::CreateDeliveryCacheStorageServiceWithApplicationId( + u64 application_id, OutInterface out_interface) { + LOG_DEBUG(Service_BCAT, "called, application_id={:016X}", application_id); + *out_interface = std::make_shared( + system, fsc.GetBCATDirectory(application_id)); + R_SUCCEED(); +} + +} // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/service_creator.h b/src/core/hle/service/bcat/service_creator.h new file mode 100644 index 000000000..50e663324 --- /dev/null +++ b/src/core/hle/service/bcat/service_creator.h @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::FileSystem { +class FileSystemController; +} + +namespace Service::BCAT { +class BcatBackend; +class IBcatService; +class IDeliveryCacheStorageService; + +class IServiceCreator final : public ServiceFramework { +public: + explicit IServiceCreator(Core::System& system_, const char* name_); + ~IServiceCreator() override; + +private: + Result CreateBcatService(ClientProcessId process_id, OutInterface out_interface); + + Result CreateDeliveryCacheStorageService( + ClientProcessId process_id, OutInterface out_interface); + + Result CreateDeliveryCacheStorageServiceWithApplicationId( + u64 application_id, OutInterface out_interface); + + std::unique_ptr backend; + Service::FileSystem::FileSystemController& fsc; +}; + +} // namespace Service::BCAT diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 06cbad268..f68c3c686 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -15,7 +15,7 @@ #include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/apm/apm.h" #include "core/hle/service/audio/audio.h" -#include "core/hle/service/bcat/bcat_module.h" +#include "core/hle/service/bcat/bcat.h" #include "core/hle/service/bpc/bpc.h" #include "core/hle/service/btdrv/btdrv.h" #include "core/hle/service/btm/btm.h" -- cgit v1.2.3