fsp-srv: Implement OutputAccessLogToSdCard

Allows games to log data to the SD.
This commit is contained in:
Zach Hilman 2019-06-28 21:02:34 -04:00
parent 5829ba1ccc
commit db2fdd0352
7 changed files with 62 additions and 27 deletions

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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();