fsp-srv: Implement OutputAccessLogToSdCard
Allows games to log data to the SD.
This commit is contained in:
		| @@ -142,7 +142,7 @@ struct System::Impl { | |||||||
|         telemetry_session = std::make_unique<Core::TelemetrySession>(); |         telemetry_session = std::make_unique<Core::TelemetrySession>(); | ||||||
|         service_manager = std::make_shared<Service::SM::ServiceManager>(); |         service_manager = std::make_shared<Service::SM::ServiceManager>(); | ||||||
|  |  | ||||||
|         Service::Init(service_manager, system, *virtual_filesystem); |         Service::Init(service_manager, system); | ||||||
|         GDBStub::Init(); |         GDBStub::Init(); | ||||||
|  |  | ||||||
|         renderer = VideoCore::CreateRenderer(emu_window, system); |         renderer = VideoCore::CreateRenderer(emu_window, system); | ||||||
|   | |||||||
| @@ -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; |     romfs_factory = nullptr; | ||||||
|     CreateFactories(vfs, false); |     CreateFactories(*system.GetFilesystem(), false); | ||||||
|     std::make_shared<FSP_LDR>()->InstallAsService(service_manager); |     std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager()); | ||||||
|     std::make_shared<FSP_PR>()->InstallAsService(service_manager); |     std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager()); | ||||||
|     std::make_shared<FSP_SRV>()->InstallAsService(service_manager); |     std::make_shared<FSP_SRV>(system.GetReporter())->InstallAsService(system.ServiceManager()); | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace Service::FileSystem | } // namespace Service::FileSystem | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id); | |||||||
| // above is called. | // above is called. | ||||||
| void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); | 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 | // 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 | // pointers and booleans. This makes using a VfsDirectory with switch services much easier and | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ | |||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/service/filesystem/filesystem.h" | #include "core/hle/service/filesystem/filesystem.h" | ||||||
| #include "core/hle/service/filesystem/fsp_srv.h" | #include "core/hle/service/filesystem/fsp_srv.h" | ||||||
|  | #include "core/reporter.h" | ||||||
|  |  | ||||||
| namespace Service::FileSystem { | namespace Service::FileSystem { | ||||||
|  |  | ||||||
| @@ -613,7 +614,7 @@ private: | |||||||
|     u64 next_entry_index = 0; |     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 |     // clang-format off | ||||||
|     static const FunctionInfo functions[] = { |     static const FunctionInfo functions[] = { | ||||||
|         {0, nullptr, "OpenFileSystem"}, |         {0, nullptr, "OpenFileSystem"}, | ||||||
| @@ -710,9 +711,9 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | |||||||
|         {1001, nullptr, "SetSaveDataSize"}, |         {1001, nullptr, "SetSaveDataSize"}, | ||||||
|         {1002, nullptr, "SetSaveDataRootPath"}, |         {1002, nullptr, "SetSaveDataRootPath"}, | ||||||
|         {1003, nullptr, "DisableAutoSaveDataCreation"}, |         {1003, nullptr, "DisableAutoSaveDataCreation"}, | ||||||
|         {1004, nullptr, "SetGlobalAccessLogMode"}, |         {1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"}, | ||||||
|         {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"}, |         {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"}, | ||||||
|         {1006, nullptr, "OutputAccessLogToSdCard"}, |         {1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"}, | ||||||
|         {1007, nullptr, "RegisterUpdatePartition"}, |         {1007, nullptr, "RegisterUpdatePartition"}, | ||||||
|         {1008, nullptr, "OpenRegisteredUpdatePartition"}, |         {1008, nullptr, "OpenRegisteredUpdatePartition"}, | ||||||
|         {1009, nullptr, "GetAndClearMemoryReportInfo"}, |         {1009, nullptr, "GetAndClearMemoryReportInfo"}, | ||||||
| @@ -814,21 +815,22 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& | |||||||
|     rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space)); |     rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp{ctx}; | ||||||
|  |     log_mode = rp.PopEnum<LogMode>(); | ||||||
|  |  | ||||||
|  |     LOG_DEBUG(Service_FS, "called, log_mode={:08X}", static_cast<u32>(log_mode)); | ||||||
|  |  | ||||||
|  |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  | } | ||||||
|  |  | ||||||
| void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { | 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}; |     IPC::ResponseBuilder rb{ctx, 3}; | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.PushEnum(LogMode::Log); |     rb.PushEnum(log_mode); | ||||||
| } | } | ||||||
|  |  | ||||||
| void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { | 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); |     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<const char*>(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 | } // namespace Service::FileSystem | ||||||
|   | |||||||
| @@ -7,15 +7,32 @@ | |||||||
| #include <memory> | #include <memory> | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
|  |  | ||||||
|  | namespace Core { | ||||||
|  | class Reporter; | ||||||
|  | } | ||||||
|  |  | ||||||
| namespace FileSys { | namespace FileSys { | ||||||
| class FileSystemBackend; | class FileSystemBackend; | ||||||
| } | } | ||||||
|  |  | ||||||
| namespace Service::FileSystem { | 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<FSP_SRV> { | class FSP_SRV final : public ServiceFramework<FSP_SRV> { | ||||||
| public: | public: | ||||||
|     explicit FSP_SRV(); |     explicit FSP_SRV(const Core::Reporter& reporter); | ||||||
|     ~FSP_SRV() override; |     ~FSP_SRV() override; | ||||||
|  |  | ||||||
| private: | private: | ||||||
| @@ -26,13 +43,18 @@ private: | |||||||
|     void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx); |     void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx); | ||||||
|     void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx); |     void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx); | ||||||
|     void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx); |     void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx); | ||||||
|  |     void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); | ||||||
|     void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); |     void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); | ||||||
|     void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); |     void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); | ||||||
|     void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); |     void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx); | ||||||
|     void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); |     void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); | ||||||
|  |     void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); | ||||||
|  |  | ||||||
|     FileSys::VirtualFile romfs; |     FileSys::VirtualFile romfs; | ||||||
|     u64 current_process_id = 0; |     u64 current_process_id = 0; | ||||||
|  |     LogMode log_mode; | ||||||
|  |  | ||||||
|  |     const Core::Reporter& reporter; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace Service::FileSystem | } // namespace Service::FileSystem | ||||||
|   | |||||||
| @@ -195,8 +195,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co | |||||||
| // Module interface | // Module interface | ||||||
|  |  | ||||||
| /// Initialize ServiceManager | /// Initialize ServiceManager | ||||||
| void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) { | ||||||
|           FileSys::VfsFilesystem& vfs) { |  | ||||||
|     // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it |     // 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. |     // here and pass it into the respective InstallInterfaces functions. | ||||||
|     auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system.CoreTiming()); |     auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system.CoreTiming()); | ||||||
| @@ -218,7 +217,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | |||||||
|     EUPLD::InstallInterfaces(*sm); |     EUPLD::InstallInterfaces(*sm); | ||||||
|     Fatal::InstallInterfaces(*sm); |     Fatal::InstallInterfaces(*sm); | ||||||
|     FGM::InstallInterfaces(*sm); |     FGM::InstallInterfaces(*sm); | ||||||
|     FileSystem::InstallInterfaces(*sm, vfs); |     FileSystem::InstallInterfaces(system); | ||||||
|     Friend::InstallInterfaces(*sm); |     Friend::InstallInterfaces(*sm); | ||||||
|     Glue::InstallInterfaces(system); |     Glue::InstallInterfaces(system); | ||||||
|     GRC::InstallInterfaces(*sm); |     GRC::InstallInterfaces(*sm); | ||||||
|   | |||||||
| @@ -182,8 +182,7 @@ private: | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Initialize ServiceManager | /// Initialize ServiceManager | ||||||
| void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system); | ||||||
|           FileSys::VfsFilesystem& vfs); |  | ||||||
|  |  | ||||||
| /// Shutdown ServiceManager | /// Shutdown ServiceManager | ||||||
| void Shutdown(); | void Shutdown(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user