1 // Copyright 2018 yuzu emulator team
2 // Licensed under GPLv2 or any later version
3 // Refer to the license.txt file included.
4 
5 #pragma once
6 
7 #include <memory>
8 #include "common/common_types.h"
9 #include "core/file_sys/directory.h"
10 #include "core/file_sys/vfs.h"
11 #include "core/hle/result.h"
12 
13 namespace Core {
14 class System;
15 }
16 
17 namespace FileSys {
18 class BISFactory;
19 class RegisteredCache;
20 class RegisteredCacheUnion;
21 class PlaceholderCache;
22 class RomFSFactory;
23 class SaveDataFactory;
24 class SDMCFactory;
25 class XCI;
26 
27 enum class BisPartitionId : u32;
28 enum class ContentRecordType : u8;
29 enum class Mode : u32;
30 enum class SaveDataSpaceId : u8;
31 enum class SaveDataType : u8;
32 enum class StorageId : u8;
33 
34 struct SaveDataAttribute;
35 struct SaveDataSize;
36 } // namespace FileSys
37 
38 namespace Service {
39 
40 namespace SM {
41 class ServiceManager;
42 } // namespace SM
43 
44 namespace FileSystem {
45 
46 enum class ContentStorageId : u32 {
47     System,
48     User,
49     SdCard,
50 };
51 
52 enum class ImageDirectoryId : u32 {
53     NAND,
54     SdCard,
55 };
56 
57 class FileSystemController {
58 public:
59     explicit FileSystemController(Core::System& system_);
60     ~FileSystemController();
61 
62     ResultCode RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory);
63     ResultCode RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory);
64     ResultCode RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory);
65     ResultCode RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory);
66 
67     void SetPackedUpdate(FileSys::VirtualFile update_raw);
68     ResultVal<FileSys::VirtualFile> OpenRomFSCurrentProcess() const;
69     ResultVal<FileSys::VirtualFile> OpenPatchedRomFS(u64 title_id,
70                                                      FileSys::ContentRecordType type) const;
71     ResultVal<FileSys::VirtualFile> OpenPatchedRomFSWithProgramIndex(
72         u64 title_id, u8 program_index, FileSys::ContentRecordType type) const;
73     ResultVal<FileSys::VirtualFile> OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
74                                               FileSys::ContentRecordType type) const;
75     ResultVal<FileSys::VirtualDir> CreateSaveData(
76         FileSys::SaveDataSpaceId space, const FileSys::SaveDataAttribute& save_struct) const;
77     ResultVal<FileSys::VirtualDir> OpenSaveData(
78         FileSys::SaveDataSpaceId space, const FileSys::SaveDataAttribute& save_struct) const;
79     ResultVal<FileSys::VirtualDir> OpenSaveDataSpace(FileSys::SaveDataSpaceId space) const;
80     ResultVal<FileSys::VirtualDir> OpenSDMC() const;
81     ResultVal<FileSys::VirtualDir> OpenBISPartition(FileSys::BisPartitionId id) const;
82     ResultVal<FileSys::VirtualFile> OpenBISPartitionStorage(FileSys::BisPartitionId id) const;
83 
84     u64 GetFreeSpaceSize(FileSys::StorageId id) const;
85     u64 GetTotalSpaceSize(FileSys::StorageId id) const;
86 
87     FileSys::SaveDataSize ReadSaveDataSize(FileSys::SaveDataType type, u64 title_id,
88                                            u128 user_id) const;
89     void WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
90                            FileSys::SaveDataSize new_value) const;
91 
92     void SetGameCard(FileSys::VirtualFile file);
93     FileSys::XCI* GetGameCard() const;
94 
95     FileSys::RegisteredCache* GetSystemNANDContents() const;
96     FileSys::RegisteredCache* GetUserNANDContents() const;
97     FileSys::RegisteredCache* GetSDMCContents() const;
98     FileSys::RegisteredCache* GetGameCardContents() const;
99 
100     FileSys::PlaceholderCache* GetSystemNANDPlaceholder() const;
101     FileSys::PlaceholderCache* GetUserNANDPlaceholder() const;
102     FileSys::PlaceholderCache* GetSDMCPlaceholder() const;
103     FileSys::PlaceholderCache* GetGameCardPlaceholder() const;
104 
105     FileSys::RegisteredCache* GetRegisteredCacheForStorage(FileSys::StorageId id) const;
106     FileSys::PlaceholderCache* GetPlaceholderCacheForStorage(FileSys::StorageId id) const;
107 
108     FileSys::VirtualDir GetSystemNANDContentDirectory() const;
109     FileSys::VirtualDir GetUserNANDContentDirectory() const;
110     FileSys::VirtualDir GetSDMCContentDirectory() const;
111 
112     FileSys::VirtualDir GetNANDImageDirectory() const;
113     FileSys::VirtualDir GetSDMCImageDirectory() const;
114 
115     FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
116     FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
117 
118     FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
119     FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;
120 
121     FileSys::VirtualDir GetBCATDirectory(u64 title_id) const;
122 
123     // Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function
124     // above is called.
125     void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
126 
127 private:
128     std::unique_ptr<FileSys::RomFSFactory> romfs_factory;
129     std::unique_ptr<FileSys::SaveDataFactory> save_data_factory;
130     std::unique_ptr<FileSys::SDMCFactory> sdmc_factory;
131     std::unique_ptr<FileSys::BISFactory> bis_factory;
132 
133     std::unique_ptr<FileSys::XCI> gamecard;
134     std::unique_ptr<FileSys::RegisteredCache> gamecard_registered;
135     std::unique_ptr<FileSys::PlaceholderCache> gamecard_placeholder;
136 
137     Core::System& system;
138 };
139 
140 void InstallInterfaces(Core::System& system);
141 
142 // A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of
143 // pointers and booleans. This makes using a VfsDirectory with switch services much easier and
144 // avoids repetitive code.
145 class VfsDirectoryServiceWrapper {
146 public:
147     explicit VfsDirectoryServiceWrapper(FileSys::VirtualDir backing);
148     ~VfsDirectoryServiceWrapper();
149 
150     /**
151      * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
152      */
153     std::string GetName() const;
154 
155     /**
156      * Create a file specified by its path
157      * @param path Path relative to the Archive
158      * @param size The size of the new file, filled with zeroes
159      * @return Result of the operation
160      */
161     ResultCode CreateFile(const std::string& path, u64 size) const;
162 
163     /**
164      * Delete a file specified by its path
165      * @param path Path relative to the archive
166      * @return Result of the operation
167      */
168     ResultCode DeleteFile(const std::string& path) const;
169 
170     /**
171      * Create a directory specified by its path
172      * @param path Path relative to the archive
173      * @return Result of the operation
174      */
175     ResultCode CreateDirectory(const std::string& path) const;
176 
177     /**
178      * Delete a directory specified by its path
179      * @param path Path relative to the archive
180      * @return Result of the operation
181      */
182     ResultCode DeleteDirectory(const std::string& path) const;
183 
184     /**
185      * Delete a directory specified by its path and anything under it
186      * @param path Path relative to the archive
187      * @return Result of the operation
188      */
189     ResultCode DeleteDirectoryRecursively(const std::string& path) const;
190 
191     /**
192      * Cleans the specified directory. This is similar to DeleteDirectoryRecursively,
193      * in that it deletes all the contents of the specified directory, however, this
194      * function does *not* delete the directory itself. It only deletes everything
195      * within it.
196      *
197      * @param path Path relative to the archive.
198      *
199      * @return Result of the operation.
200      */
201     ResultCode CleanDirectoryRecursively(const std::string& path) const;
202 
203     /**
204      * Rename a File specified by its path
205      * @param src_path Source path relative to the archive
206      * @param dest_path Destination path relative to the archive
207      * @return Result of the operation
208      */
209     ResultCode RenameFile(const std::string& src_path, const std::string& dest_path) const;
210 
211     /**
212      * Rename a Directory specified by its path
213      * @param src_path Source path relative to the archive
214      * @param dest_path Destination path relative to the archive
215      * @return Result of the operation
216      */
217     ResultCode RenameDirectory(const std::string& src_path, const std::string& dest_path) const;
218 
219     /**
220      * Open a file specified by its path, using the specified mode
221      * @param path Path relative to the archive
222      * @param mode Mode to open the file with
223      * @return Opened file, or error code
224      */
225     ResultVal<FileSys::VirtualFile> OpenFile(const std::string& path, FileSys::Mode mode) const;
226 
227     /**
228      * Open a directory specified by its path
229      * @param path Path relative to the archive
230      * @return Opened directory, or error code
231      */
232     ResultVal<FileSys::VirtualDir> OpenDirectory(const std::string& path);
233 
234     /**
235      * Get the type of the specified path
236      * @return The type of the specified path or error code
237      */
238     ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const;
239 
240 private:
241     FileSys::VirtualDir backing;
242 };
243 
244 } // namespace FileSystem
245 } // namespace Service
246