// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "common/common_types.h"
#include "core/file_sys/directory.h"
#include "core/file_sys/vfs.h"
#include "core/hle/result.h"
namespace Core {
class System;
}
namespace FileSys {
class BISFactory;
class RegisteredCache;
class RegisteredCacheUnion;
class PlaceholderCache;
class RomFSFactory;
class SaveDataFactory;
class SDMCFactory;
class XCI;
enum class BisPartitionId : u32;
enum class ContentRecordType : u8;
enum class Mode : u32;
enum class SaveDataSpaceId : u8;
enum class SaveDataType : u8;
enum class StorageId : u8;
struct SaveDataAttribute;
struct SaveDataSize;
} // namespace FileSys
namespace Service {
namespace SM {
class ServiceManager;
} // namespace SM
namespace FileSystem {
enum class ContentStorageId : u32 {
System,
User,
SdCard,
};
enum class ImageDirectoryId : u32 {
NAND,
SdCard,
};
class FileSystemController {
public:
explicit FileSystemController(Core::System& system_);
~FileSystemController();
Result RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory);
Result RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory);
Result RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory);
Result RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory);
void SetPackedUpdate(FileSys::VirtualFile update_raw);
FileSys::VirtualFile OpenRomFSCurrentProcess() const;
FileSys::VirtualFile OpenPatchedRomFS(u64 title_id, FileSys::ContentRecordType type) const;
FileSys::VirtualFile OpenPatchedRomFSWithProgramIndex(u64 title_id, u8 program_index,
FileSys::ContentRecordType type) const;
FileSys::VirtualFile OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
FileSys::ContentRecordType type) const;
Result CreateSaveData(FileSys::VirtualDir* out_save_data, FileSys::SaveDataSpaceId space,
const FileSys::SaveDataAttribute& save_struct) const;
Result OpenSaveData(FileSys::VirtualDir* out_save_data, FileSys::SaveDataSpaceId space,
const FileSys::SaveDataAttribute& save_struct) const;
Result OpenSaveDataSpace(FileSys::VirtualDir* out_save_data_space,
FileSys::SaveDataSpaceId space) const;
Result OpenSDMC(FileSys::VirtualDir* out_sdmc) const;
Result OpenBISPartition(FileSys::VirtualDir* out_bis_partition,
FileSys::BisPartitionId id) const;
Result OpenBISPartitionStorage(FileSys::VirtualFile* out_bis_partition_storage,
FileSys::BisPartitionId id) const;
u64 GetFreeSpaceSize(FileSys::StorageId id) const;
u64 GetTotalSpaceSize(FileSys::StorageId id) const;
FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id,
u128 user_id) const;
void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
FileSys::SaveDataSize new_value) const;
void SetGameCard(FileSys::VirtualFile file);
FileSys::XCI* GetGameCard() const;
FileSys::RegisteredCache* GetSystemNANDContents() const;
FileSys::RegisteredCache* GetUserNANDContents() const;
FileSys::RegisteredCache* GetSDMCContents() const;
FileSys::RegisteredCache* GetGameCardContents() const;
FileSys::PlaceholderCache* GetSystemNANDPlaceholder() const;
FileSys::PlaceholderCache* GetUserNANDPlaceholder() const;
FileSys::PlaceholderCache* GetSDMCPlaceholder() const;
FileSys::PlaceholderCache* GetGameCardPlaceholder() const;
FileSys::RegisteredCache* GetRegisteredCacheForStorage(FileSys::StorageId id) const;
FileSys::PlaceholderCache* GetPlaceholderCacheForStorage(FileSys::StorageId id) const;
FileSys::VirtualDir GetSystemNANDContentDirectory() const;
FileSys::VirtualDir GetUserNANDContentDirectory() const;
FileSys::VirtualDir GetSDMCContentDirectory() const;
FileSys::VirtualDir GetNANDImageDirectory() const;
FileSys::VirtualDir GetSDMCImageDirectory() const;
FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
FileSys::VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const;
FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;
FileSys::VirtualDir GetBCATDirectory(u64 title_id) const;
void SetAutoSaveDataCreation(bool enable);
// Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function
// above is called.
void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
private:
std::unique_ptr<FileSys::RomFSFactory> romfs_factory;
std::unique_ptr<FileSys::SaveDataFactory> save_data_factory;
std::unique_ptr<FileSys::SDMCFactory> sdmc_factory;
std::unique_ptr<FileSys::BISFactory> bis_factory;
std::unique_ptr<FileSys::XCI> gamecard;
std::unique_ptr<FileSys::RegisteredCache> gamecard_registered;
std::unique_ptr<FileSys::PlaceholderCache> gamecard_placeholder;
Core::System& system;
};
void LoopProcess(Core::System& system);
// A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of
// pointers and booleans. This makes using a VfsDirectory with switch services much easier and
// avoids repetitive code.
class VfsDirectoryServiceWrapper {
public:
explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing);
~VfsDirectoryServiceWrapper();
/**
* Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
*/
std::string GetName() const;
/**
* Create a file specified by its path
* @param path Path relative to the Archive
* @param size The size of the new file, filled with zeroes
* @return Result of the operation
*/
Result CreateFile(const std::string& path, u64 size) const;
/**
* Delete a file specified by its path
* @param path Path relative to the archive
* @return Result of the operation
*/
Result DeleteFile(const std::string& path) const;
/**
* Create a directory specified by its path
* @param path Path relative to the archive
* @return Result of the operation
*/
Result CreateDirectory(const std::string& path) const;
/**
* Delete a directory specified by its path
* @param path Path relative to the archive
* @return Result of the operation
*/
Result DeleteDirectory(const std::string& path) const;
/**
* Delete a directory specified by its path and anything under it
* @param path Path relative to the archive
* @return Result of the operation
*/
Result DeleteDirectoryRecursively(const std::string& path) const;
/**
* Cleans the specified directory. This is similar to DeleteDirectoryRecursively,
* in that it deletes all the contents of the specified directory, however, this
* function does *not* delete the directory itself. It only deletes everything
* within it.
*
* @param path Path relative to the archive.
*
* @return Result of the operation.
*/
Result CleanDirectoryRecursively(const std::string& path) const;
/**
* Rename a File specified by its path
* @param src_path Source path relative to the archive
* @param dest_path Destination path relative to the archive
* @return Result of the operation
*/
Result RenameFile(const std::string& src_path, const std::string& dest_path) const;
/**
* Rename a Directory specified by its path
* @param src_path Source path relative to the archive
* @param dest_path Destination path relative to the archive
* @return Result of the operation
*/
Result RenameDirectory(const std::string& src_path, const std::string& dest_path) const;
/**
* Open a file specified by its path, using the specified mode
* @param path Path relative to the archive
* @param mode Mode to open the file with
* @return Opened file, or error code
*/
Result OpenFile(FileSys::VirtualFile* out_file, const std::string& path,
FileSys::Mode mode) const;
/**
* Open a directory specified by its path
* @param path Path relative to the archive
* @return Opened directory, or error code
*/
Result OpenDirectory(FileSys::VirtualDir* out_directory, const std::string& path);
/**
* Get the type of the specified path
* @return The type of the specified path or error code
*/
Result GetEntryType(FileSys::EntryType* out_entry_type, const std::string& path) const;
/**
* Get the timestamp of the specified path
* @return The timestamp of the specified path or error code
*/
Result GetFileTimeStampRaw(FileSys::FileTimeStampRaw* out_time_stamp_raw,
const std::string& path) const;
private:
FileSys::VirtualDir backing;
};
} // namespace FileSystem
} // namespace Service