From db2fdd0352d023787fcac032101e1e36fb8aa03f Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Jun 2019 21:02:34 -0400 Subject: [PATCH 1/3] fsp-srv: Implement OutputAccessLogToSdCard Allows games to log data to the SD. --- src/core/core.cpp | 2 +- .../hle/service/filesystem/filesystem.cpp | 10 ++--- src/core/hle/service/filesystem/filesystem.h | 2 +- src/core/hle/service/filesystem/fsp_srv.cpp | 43 +++++++++++++------ src/core/hle/service/filesystem/fsp_srv.h | 24 ++++++++++- src/core/hle/service/service.cpp | 5 +-- src/core/hle/service/service.h | 3 +- 7 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index df26eb109..678fa8cea 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -142,7 +142,7 @@ struct System::Impl { telemetry_session = std::make_unique(); service_manager = std::make_shared(); - Service::Init(service_manager, system, *virtual_filesystem); + Service::Init(service_manager, system); GDBStub::Init(); renderer = VideoCore::CreateRenderer(emu_window, system); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 1ebfeb4bf..8ce110dd1 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -472,12 +472,12 @@ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) { } } -void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs) { +void InstallInterfaces(Core::System& system) { romfs_factory = nullptr; - CreateFactories(vfs, false); - std::make_shared()->InstallAsService(service_manager); - std::make_shared()->InstallAsService(service_manager); - std::make_shared()->InstallAsService(service_manager); + CreateFactories(*system.GetFilesystem(), false); + std::make_shared()->InstallAsService(system.ServiceManager()); + std::make_shared()->InstallAsService(system.ServiceManager()); + std::make_shared(system.GetReporter())->InstallAsService(system.ServiceManager()); } } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 6481f237c..3849dd89e 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -65,7 +65,7 @@ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id); // above is called. void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); -void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs); +void InstallInterfaces(Core::System& system); // A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of // pointers and booleans. This makes using a VfsDirectory with switch services much easier and diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index e7df8fd98..bfe0c32b7 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -26,6 +26,7 @@ #include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp_srv.h" +#include "core/reporter.h" namespace Service::FileSystem { @@ -613,7 +614,7 @@ private: u64 next_entry_index = 0; }; -FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { +FSP_SRV::FSP_SRV(const Core::Reporter& reporter) : ServiceFramework("fsp-srv"), reporter(reporter) { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "OpenFileSystem"}, @@ -710,9 +711,9 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { {1001, nullptr, "SetSaveDataSize"}, {1002, nullptr, "SetSaveDataRootPath"}, {1003, nullptr, "DisableAutoSaveDataCreation"}, - {1004, nullptr, "SetGlobalAccessLogMode"}, + {1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"}, {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"}, - {1006, nullptr, "OutputAccessLogToSdCard"}, + {1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"}, {1007, nullptr, "RegisterUpdatePartition"}, {1008, nullptr, "OpenRegisteredUpdatePartition"}, {1009, nullptr, "GetAndClearMemoryReportInfo"}, @@ -814,21 +815,22 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& rb.PushIpcInterface(std::make_shared(space)); } +void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + log_mode = rp.PopEnum(); + + LOG_DEBUG(Service_FS, "called, log_mode={:08X}", static_cast(log_mode)); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); + LOG_WARNING(Service_FS, "called"); - enum class LogMode : u32 { - Off, - Log, - RedirectToSdCard, - LogToSdCard = Log | RedirectToSdCard, - }; - - // Given we always want to receive logging information, - // we always specify logging as enabled. IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.PushEnum(LogMode::Log); + rb.PushEnum(log_mode); } void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { @@ -902,4 +904,17 @@ void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ct rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); } +void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) { + const auto raw = ctx.ReadBuffer(); + auto log = Common::StringFromFixedZeroTerminatedBuffer( + reinterpret_cast(raw.data()), raw.size()); + + LOG_DEBUG(Service_FS, "called, log='{}'", log); + + reporter.SaveFilesystemAccessReport(log_mode, std::move(log)); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index d7572ba7a..bfaeaad5d 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -7,15 +7,32 @@ #include #include "core/hle/service/service.h" +namespace Core { +class Reporter; +} + namespace FileSys { class FileSystemBackend; } namespace Service::FileSystem { +enum class AccessLogVersion : u32 { + V7_0_0 = 2, + + Latest = V7_0_0, +}; + +enum class LogMode : u32 { + Off, + Log, + RedirectToSdCard, + LogToSdCard = Log | RedirectToSdCard, +}; + class FSP_SRV final : public ServiceFramework { public: - explicit FSP_SRV(); + explicit FSP_SRV(const Core::Reporter& reporter); ~FSP_SRV() override; private: @@ -26,13 +43,18 @@ private: void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx); void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx); void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx); + void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); + void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); FileSys::VirtualFile romfs; u64 current_process_id = 0; + LogMode log_mode; + + const Core::Reporter& reporter; }; } // namespace Service::FileSystem diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index ec9d755b7..60155f2d0 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -195,8 +195,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co // Module interface /// Initialize ServiceManager -void Init(std::shared_ptr& sm, Core::System& system, - FileSys::VfsFilesystem& vfs) { +void Init(std::shared_ptr& sm, Core::System& system) { // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it // here and pass it into the respective InstallInterfaces functions. auto nv_flinger = std::make_shared(system.CoreTiming()); @@ -218,7 +217,7 @@ void Init(std::shared_ptr& sm, Core::System& system, EUPLD::InstallInterfaces(*sm); Fatal::InstallInterfaces(*sm); FGM::InstallInterfaces(*sm); - FileSystem::InstallInterfaces(*sm, vfs); + FileSystem::InstallInterfaces(system); Friend::InstallInterfaces(*sm); Glue::InstallInterfaces(system); GRC::InstallInterfaces(*sm); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index abbfe5524..c6c4bdae5 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -182,8 +182,7 @@ private: }; /// Initialize ServiceManager -void Init(std::shared_ptr& sm, Core::System& system, - FileSys::VfsFilesystem& vfs); +void Init(std::shared_ptr& sm, Core::System& system); /// Shutdown ServiceManager void Shutdown(); From 554e2f2f983824bee174465c79b9ad3c27e8208f Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Jun 2019 21:02:50 -0400 Subject: [PATCH 2/3] reporter: Add report class for filesystem access logs --- src/core/reporter.cpp | 18 ++++++++++++++++++ src/core/reporter.h | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 774022569..059467318 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -335,6 +335,24 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result, SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp)); } +void Reporter::SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode, + std::string log_message) const { + if (!IsReportingEnabled()) + return; + + const auto timestamp = GetTimestamp(); + const auto title_id = system.CurrentProcess()->GetTitleID(); + json out; + + out["yuzu_version"] = GetYuzuVersionData(); + out["report_common"] = GetReportCommonData(title_id, RESULT_SUCCESS, timestamp); + + out["log_mode"] = fmt::format("{:08X}", static_cast(log_mode)); + out["log_message"] = std::move(log_message); + + SaveToFile(std::move(out), GetPath("filesystem_access_report", title_id, timestamp)); +} + void Reporter::SaveUserReport() const { if (!IsReportingEnabled()) return; diff --git a/src/core/reporter.h b/src/core/reporter.h index 3de19c0f7..ba95c369e 100644 --- a/src/core/reporter.h +++ b/src/core/reporter.h @@ -14,6 +14,10 @@ namespace Kernel { class HLERequestContext; } // namespace Kernel +namespace Service::FileSystem { +enum class LogMode : u32; +} + namespace Core { class Reporter { @@ -45,6 +49,9 @@ public: std::optional custom_text_main = {}, std::optional custom_text_detail = {}) const; + void SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode, + std::string log_message) const; + void SaveUserReport() const; private: From d40f38967e15372cf4b85c4d862ccb35b3befa40 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 28 Jun 2019 21:05:37 -0400 Subject: [PATCH 3/3] fsp-srv: Implement GetAccessLogVersionInfo Returns some misc. data about logging to help the game determine if it should log. --- src/core/hle/service/filesystem/fsp_srv.cpp | 13 +++++++++++-- src/core/hle/service/filesystem/fsp_srv.h | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index bfe0c32b7..d3cd46a9b 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -718,7 +718,7 @@ FSP_SRV::FSP_SRV(const Core::Reporter& reporter) : ServiceFramework("fsp-srv"), {1008, nullptr, "OpenRegisteredUpdatePartition"}, {1009, nullptr, "GetAndClearMemoryReportInfo"}, {1010, nullptr, "SetDataStorageRedirectTarget"}, - {1011, nullptr, "OutputAccessLogToSdCard2"}, + {1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"}, {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, {1200, nullptr, "OpenMultiCommitManager"}, @@ -826,7 +826,7 @@ void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { } void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "called"); + LOG_DEBUG(Service_FS, "called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); @@ -917,4 +917,13 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } +void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushEnum(AccessLogVersion::Latest); + rb.Push(access_log_program_index); +} + } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index bfaeaad5d..b5486a193 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -49,10 +49,12 @@ private: void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); + void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx); FileSys::VirtualFile romfs; u64 current_process_id = 0; - LogMode log_mode; + u32 access_log_program_index = 0; + LogMode log_mode = LogMode::LogToSdCard; const Core::Reporter& reporter; };