summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
authorGravatar darkf2014-12-29 19:47:41 -0800
committerGravatar darkf2014-12-29 19:47:41 -0800
commit8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch)
treef1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/file_sys
parentAdd comment regarding __WIN32__ in SkyEye code (diff)
parentMerge pull request #367 from bunnei/usat_ssat (diff)
downloadyuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz
yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz
yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip
Fix merge conflicts
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/archive.h246
-rw-r--r--src/core/file_sys/archive_backend.h243
-rw-r--r--src/core/file_sys/archive_romfs.cpp101
-rw-r--r--src/core/file_sys/archive_romfs.h77
-rw-r--r--src/core/file_sys/archive_savedata.cpp33
-rw-r--r--src/core/file_sys/archive_savedata.h31
-rw-r--r--src/core/file_sys/archive_sdmc.cpp122
-rw-r--r--src/core/file_sys/archive_sdmc.h88
-rw-r--r--src/core/file_sys/archive_systemsavedata.cpp39
-rw-r--r--src/core/file_sys/archive_systemsavedata.h33
-rw-r--r--src/core/file_sys/directory_backend.h (renamed from src/core/file_sys/directory.h)14
-rw-r--r--src/core/file_sys/directory_romfs.cpp16
-rw-r--r--src/core/file_sys/directory_romfs.h12
-rw-r--r--src/core/file_sys/directory_sdmc.cpp81
-rw-r--r--src/core/file_sys/directory_sdmc.h48
-rw-r--r--src/core/file_sys/disk_archive.cpp188
-rw-r--r--src/core/file_sys/disk_archive.h103
-rw-r--r--src/core/file_sys/file_backend.h (renamed from src/core/file_sys/file.h)13
-rw-r--r--src/core/file_sys/file_romfs.cpp53
-rw-r--r--src/core/file_sys/file_romfs.h16
-rw-r--r--src/core/file_sys/file_sdmc.cpp107
-rw-r--r--src/core/file_sys/file_sdmc.h75
22 files changed, 793 insertions, 946 deletions
diff --git a/src/core/file_sys/archive.h b/src/core/file_sys/archive.h
deleted file mode 100644
index 2e79bb883..000000000
--- a/src/core/file_sys/archive.h
+++ /dev/null
@@ -1,246 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8
9#include "common/common_types.h"
10#include "common/string_util.h"
11#include "common/bit_field.h"
12
13#include "core/file_sys/file.h"
14#include "core/file_sys/directory.h"
15
16#include "core/mem_map.h"
17#include "core/hle/kernel/kernel.h"
18
19////////////////////////////////////////////////////////////////////////////////////////////////////
20// FileSys namespace
21
22namespace FileSys {
23
24// Path string type
25enum LowPathType : u32 {
26 Invalid = 0,
27 Empty = 1,
28 Binary = 2,
29 Char = 3,
30 Wchar = 4
31};
32
33union Mode {
34 u32 hex;
35 BitField<0, 1, u32> read_flag;
36 BitField<1, 1, u32> write_flag;
37 BitField<2, 1, u32> create_flag;
38};
39
40class Path {
41public:
42
43 Path():
44 type(Invalid)
45 {
46 }
47
48 Path(LowPathType type, u32 size, u32 pointer):
49 type(type)
50 {
51 switch (type) {
52 case Binary:
53 {
54 u8* data = Memory::GetPointer(pointer);
55 binary = std::vector<u8>(data, data + size);
56 break;
57 }
58 case Char:
59 {
60 const char* data = reinterpret_cast<const char*>(Memory::GetPointer(pointer));
61 string = std::string(data, size - 1); // Data is always null-terminated.
62 break;
63 }
64 case Wchar:
65 {
66 const char16_t* data = reinterpret_cast<const char16_t*>(Memory::GetPointer(pointer));
67 u16str = std::u16string(data, size/2 - 1); // Data is always null-terminated.
68 break;
69 }
70 }
71 }
72
73 LowPathType GetType() const {
74 return type;
75 }
76
77 /**
78 * Gets the string representation of the path for debugging
79 * @return String representation of the path for debugging
80 */
81 const std::string DebugStr() const {
82 switch (GetType()) {
83 case Invalid:
84 return "[Invalid]";
85 case Empty:
86 return "[Empty]";
87 case Binary:
88 {
89 std::stringstream res;
90 res << "[Binary: ";
91 for (unsigned byte : binary)
92 res << std::hex << std::setw(2) << std::setfill('0') << byte;
93 res << ']';
94 return res.str();
95 }
96 case Char:
97 return "[Char: " + AsString() + ']';
98 case Wchar:
99 return "[Wchar: " + AsString() + ']';
100 default:
101 ERROR_LOG(KERNEL, "LowPathType cannot be converted to string!");
102 return {};
103 }
104 }
105
106 const std::string AsString() const {
107 switch (GetType()) {
108 case Char:
109 return string;
110 case Wchar:
111 return Common::UTF16ToUTF8(u16str);
112 case Empty:
113 return {};
114 default:
115 ERROR_LOG(KERNEL, "LowPathType cannot be converted to string!");
116 return {};
117 }
118 }
119
120 const std::u16string AsU16Str() const {
121 switch (GetType()) {
122 case Char:
123 return Common::UTF8ToUTF16(string);
124 case Wchar:
125 return u16str;
126 case Empty:
127 return {};
128 default:
129 ERROR_LOG(KERNEL, "LowPathType cannot be converted to u16string!");
130 return {};
131 }
132 }
133
134 const std::vector<u8> AsBinary() const {
135 switch (GetType()) {
136 case Binary:
137 return binary;
138 case Char:
139 return std::vector<u8>(string.begin(), string.end());
140 case Wchar:
141 return std::vector<u8>(u16str.begin(), u16str.end());
142 case Empty:
143 return {};
144 default:
145 ERROR_LOG(KERNEL, "LowPathType cannot be converted to binary!");
146 return {};
147 }
148 }
149
150private:
151 LowPathType type;
152 std::vector<u8> binary;
153 std::string string;
154 std::u16string u16str;
155};
156
157class Archive : NonCopyable {
158public:
159 /// Supported archive types
160 enum class IdCode : u32 {
161 RomFS = 0x00000003,
162 SaveData = 0x00000004,
163 ExtSaveData = 0x00000006,
164 SharedExtSaveData = 0x00000007,
165 SystemSaveData = 0x00000008,
166 SDMC = 0x00000009,
167 SDMCWriteOnly = 0x0000000A,
168 };
169
170 Archive() { }
171 virtual ~Archive() { }
172
173 /**
174 * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.)
175 * @return IdCode of the archive
176 */
177 virtual IdCode GetIdCode() const = 0;
178
179 /**
180 * Open a file specified by its path, using the specified mode
181 * @param path Path relative to the archive
182 * @param mode Mode to open the file with
183 * @return Opened file, or nullptr
184 */
185 virtual std::unique_ptr<File> OpenFile(const Path& path, const Mode mode) const = 0;
186
187 /**
188 * Delete a file specified by its path
189 * @param path Path relative to the archive
190 * @return Whether the file could be deleted
191 */
192 virtual bool DeleteFile(const FileSys::Path& path) const = 0;
193
194 /**
195 * Delete a directory specified by its path
196 * @param path Path relative to the archive
197 * @return Whether the directory could be deleted
198 */
199 virtual bool DeleteDirectory(const FileSys::Path& path) const = 0;
200
201 /**
202 * Create a directory specified by its path
203 * @param path Path relative to the archive
204 * @return Whether the directory could be created
205 */
206 virtual bool CreateDirectory(const Path& path) const = 0;
207
208 /**
209 * Open a directory specified by its path
210 * @param path Path relative to the archive
211 * @return Opened directory, or nullptr
212 */
213 virtual std::unique_ptr<Directory> OpenDirectory(const Path& path) const = 0;
214
215 /**
216 * Read data from the archive
217 * @param offset Offset in bytes to start reading data from
218 * @param length Length in bytes of data to read from archive
219 * @param buffer Buffer to read data into
220 * @return Number of bytes read
221 */
222 virtual size_t Read(const u64 offset, const u32 length, u8* buffer) const = 0;
223
224 /**
225 * Write data to the archive
226 * @param offset Offset in bytes to start writing data to
227 * @param length Length in bytes of data to write to archive
228 * @param buffer Buffer to write data from
229 * @param flush The flush parameters (0 == do not flush)
230 * @return Number of bytes written
231 */
232 virtual size_t Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) = 0;
233
234 /**
235 * Get the size of the archive in bytes
236 * @return Size of the archive in bytes
237 */
238 virtual size_t GetSize() const = 0;
239
240 /**
241 * Set the size of the archive in bytes
242 */
243 virtual void SetSize(const u64 size) = 0;
244};
245
246} // namespace FileSys
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h
new file mode 100644
index 000000000..e153917ea
--- /dev/null
+++ b/src/core/file_sys/archive_backend.h
@@ -0,0 +1,243 @@
1// Copyright 2014 Citra Emulator Project
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
9#include "common/common_types.h"
10#include "common/string_util.h"
11#include "common/bit_field.h"
12
13#include "core/file_sys/file_backend.h"
14#include "core/file_sys/directory_backend.h"
15
16#include "core/mem_map.h"
17#include "core/hle/kernel/kernel.h"
18
19////////////////////////////////////////////////////////////////////////////////////////////////////
20// FileSys namespace
21
22namespace FileSys {
23
24// Path string type
25enum LowPathType : u32 {
26 Invalid = 0,
27 Empty = 1,
28 Binary = 2,
29 Char = 3,
30 Wchar = 4
31};
32
33union Mode {
34 u32 hex;
35 BitField<0, 1, u32> read_flag;
36 BitField<1, 1, u32> write_flag;
37 BitField<2, 1, u32> create_flag;
38};
39
40class Path {
41public:
42
43 Path() : type(Invalid) {
44 }
45
46 Path(const char* path) : type(Char), string(path) {
47 }
48
49 Path(LowPathType type, u32 size, u32 pointer) : type(type) {
50 switch (type) {
51 case Binary:
52 {
53 u8* data = Memory::GetPointer(pointer);
54 binary = std::vector<u8>(data, data + size);
55 break;
56 }
57
58 case Char:
59 {
60 const char* data = reinterpret_cast<const char*>(Memory::GetPointer(pointer));
61 string = std::string(data, size - 1); // Data is always null-terminated.
62 break;
63 }
64
65 case Wchar:
66 {
67 const char16_t* data = reinterpret_cast<const char16_t*>(Memory::GetPointer(pointer));
68 u16str = std::u16string(data, size/2 - 1); // Data is always null-terminated.
69 break;
70 }
71
72 default:
73 break;
74 }
75 }
76
77 LowPathType GetType() const {
78 return type;
79 }
80
81 /**
82 * Gets the string representation of the path for debugging
83 * @return String representation of the path for debugging
84 */
85 const std::string DebugStr() const {
86 switch (GetType()) {
87 case Invalid:
88 return "[Invalid]";
89 case Empty:
90 return "[Empty]";
91 case Binary:
92 {
93 std::stringstream res;
94 res << "[Binary: ";
95 for (unsigned byte : binary)
96 res << std::hex << std::setw(2) << std::setfill('0') << byte;
97 res << ']';
98 return res.str();
99 }
100 case Char:
101 return "[Char: " + AsString() + ']';
102 case Wchar:
103 return "[Wchar: " + AsString() + ']';
104 }
105 }
106
107 const std::string AsString() const {
108 switch (GetType()) {
109 case Char:
110 return string;
111 case Wchar:
112 return Common::UTF16ToUTF8(u16str);
113 case Empty:
114 return {};
115 case Invalid:
116 case Binary:
117 // TODO(yuriks): Add assert
118 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
119 return {};
120 }
121 }
122
123 const std::u16string AsU16Str() const {
124 switch (GetType()) {
125 case Char:
126 return Common::UTF8ToUTF16(string);
127 case Wchar:
128 return u16str;
129 case Empty:
130 return {};
131 case Invalid:
132 case Binary:
133 // TODO(yuriks): Add assert
134 LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
135 return {};
136 }
137 }
138
139 const std::vector<u8> AsBinary() const {
140 switch (GetType()) {
141 case Binary:
142 return binary;
143 case Char:
144 return std::vector<u8>(string.begin(), string.end());
145 case Wchar:
146 {
147 // use two u8 for each character of u16str
148 std::vector<u8> to_return(u16str.size() * 2);
149 for (size_t i = 0; i < u16str.size(); ++i) {
150 u16 tmp_char = u16str.at(i);
151 to_return[i*2] = (tmp_char & 0xFF00) >> 8;
152 to_return[i*2 + 1] = (tmp_char & 0x00FF);
153 }
154 return to_return;
155 }
156 case Empty:
157 return {};
158 case Invalid:
159 // TODO(yuriks): Add assert
160 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
161 return {};
162 }
163 }
164
165private:
166 LowPathType type;
167 std::vector<u8> binary;
168 std::string string;
169 std::u16string u16str;
170};
171
172class ArchiveBackend : NonCopyable {
173public:
174 virtual ~ArchiveBackend() {
175 }
176
177 /**
178 * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
179 */
180 virtual std::string GetName() const = 0;
181
182 /**
183 * Open a file specified by its path, using the specified mode
184 * @param path Path relative to the archive
185 * @param mode Mode to open the file with
186 * @return Opened file, or nullptr
187 */
188 virtual std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const = 0;
189
190 /**
191 * Delete a file specified by its path
192 * @param path Path relative to the archive
193 * @return Whether the file could be deleted
194 */
195 virtual bool DeleteFile(const Path& path) const = 0;
196
197 /**
198 * Rename a File specified by its path
199 * @param src_path Source path relative to the archive
200 * @param dest_path Destination path relative to the archive
201 * @return Whether rename succeeded
202 */
203 virtual bool RenameFile(const Path& src_path, const Path& dest_path) const = 0;
204
205 /**
206 * Delete a directory specified by its path
207 * @param path Path relative to the archive
208 * @return Whether the directory could be deleted
209 */
210 virtual bool DeleteDirectory(const Path& path) const = 0;
211
212 /**
213 * Create a file specified by its path
214 * @param path Path relative to the Archive
215 * @param size The size of the new file, filled with zeroes
216 * @return File creation result code
217 */
218 virtual ResultCode CreateFile(const Path& path, u32 size) const = 0;
219
220 /**
221 * Create a directory specified by its path
222 * @param path Path relative to the archive
223 * @return Whether the directory could be created
224 */
225 virtual bool CreateDirectory(const Path& path) const = 0;
226
227 /**
228 * Rename a Directory specified by its path
229 * @param src_path Source path relative to the archive
230 * @param dest_path Destination path relative to the archive
231 * @return Whether rename succeeded
232 */
233 virtual bool RenameDirectory(const Path& src_path, const Path& dest_path) const = 0;
234
235 /**
236 * Open a directory specified by its path
237 * @param path Path relative to the archive
238 * @return Opened directory, or nullptr
239 */
240 virtual std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const = 0;
241};
242
243} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
index 53dc57954..fdaf73179 100644
--- a/src/core/file_sys/archive_romfs.cpp
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -1,8 +1,11 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory>
6
5#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/make_unique.h"
6 9
7#include "core/file_sys/archive_romfs.h" 10#include "core/file_sys/archive_romfs.h"
8#include "core/file_sys/directory_romfs.h" 11#include "core/file_sys/directory_romfs.h"
@@ -16,101 +19,47 @@ namespace FileSys {
16Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { 19Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) {
17 // Load the RomFS from the app 20 // Load the RomFS from the app
18 if (Loader::ResultStatus::Success != app_loader.ReadRomFS(raw_data)) { 21 if (Loader::ResultStatus::Success != app_loader.ReadRomFS(raw_data)) {
19 WARN_LOG(FILESYS, "Unable to read RomFS!"); 22 LOG_ERROR(Service_FS, "Unable to read RomFS!");
20 } 23 }
21} 24}
22 25
23Archive_RomFS::~Archive_RomFS() { 26std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
24} 27 return Common::make_unique<File_RomFS>(this);
25
26/**
27 * Open a file specified by its path, using the specified mode
28 * @param path Path relative to the archive
29 * @param mode Mode to open the file with
30 * @return Opened file, or nullptr
31 */
32std::unique_ptr<File> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
33 return std::unique_ptr<File>(new File_RomFS);
34} 28}
35 29
36/** 30bool Archive_RomFS::DeleteFile(const Path& path) const {
37 * Delete a file specified by its path 31 LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS.");
38 * @param path Path relative to the archive
39 * @return Whether the file could be deleted
40 */
41bool Archive_RomFS::DeleteFile(const FileSys::Path& path) const {
42 ERROR_LOG(FILESYS, "Attempted to delete a file from ROMFS.");
43 return false; 32 return false;
44} 33}
45 34
46/** 35bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const {
47 * Delete a directory specified by its path 36 LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
48 * @param path Path relative to the archive
49 * @return Whether the directory could be deleted
50 */
51bool Archive_RomFS::DeleteDirectory(const FileSys::Path& path) const {
52 ERROR_LOG(FILESYS, "Attempted to delete a directory from ROMFS.");
53 return false; 37 return false;
54} 38}
55 39
56/** 40bool Archive_RomFS::DeleteDirectory(const Path& path) const {
57 * Create a directory specified by its path 41 LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS.");
58 * @param path Path relative to the archive
59 * @return Whether the directory could be created
60 */
61bool Archive_RomFS::CreateDirectory(const Path& path) const {
62 ERROR_LOG(FILESYS, "Attempted to create a directory in ROMFS.");
63 return false; 42 return false;
64} 43}
65 44
66/** 45ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const {
67 * Open a directory specified by its path 46 LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS.");
68 * @param path Path relative to the archive 47 // TODO: Verify error code
69 * @return Opened directory, or nullptr 48 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
70 */
71std::unique_ptr<Directory> Archive_RomFS::OpenDirectory(const Path& path) const {
72 return std::unique_ptr<Directory>(new Directory_RomFS);
73} 49}
74 50
75/** 51bool Archive_RomFS::CreateDirectory(const Path& path) const {
76 * Read data from the archive 52 LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS.");
77 * @param offset Offset in bytes to start reading data from 53 return false;
78 * @param length Length in bytes of data to read from archive
79 * @param buffer Buffer to read data into
80 * @return Number of bytes read
81 */
82size_t Archive_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
83 DEBUG_LOG(FILESYS, "called offset=%llu, length=%d", offset, length);
84 memcpy(buffer, &raw_data[(u32)offset], length);
85 return length;
86}
87
88/**
89 * Write data to the archive
90 * @param offset Offset in bytes to start writing data to
91 * @param length Length in bytes of data to write to archive
92 * @param buffer Buffer to write data from
93 * @param flush The flush parameters (0 == do not flush)
94 * @return Number of bytes written
95 */
96size_t Archive_RomFS::Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) {
97 ERROR_LOG(FILESYS, "Attempted to write to ROMFS.");
98 return 0;
99} 54}
100 55
101/** 56bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const {
102 * Get the size of the archive in bytes 57 LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
103 * @return Size of the archive in bytes 58 return false;
104 */
105size_t Archive_RomFS::GetSize() const {
106 return sizeof(u8) * raw_data.size();
107} 59}
108 60
109/** 61std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const {
110 * Set the size of the archive in bytes 62 return Common::make_unique<Directory_RomFS>();
111 */
112void Archive_RomFS::SetSize(const u64 size) {
113 ERROR_LOG(FILESYS, "Attempted to set the size of ROMFS");
114} 63}
115 64
116} // namespace FileSys 65} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
index 0649dde99..5e918f92d 100644
--- a/src/core/file_sys/archive_romfs.h
+++ b/src/core/file_sys/archive_romfs.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
@@ -8,7 +8,7 @@
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10 10
11#include "core/file_sys/archive.h" 11#include "core/file_sys/archive_backend.h"
12#include "core/loader/loader.h" 12#include "core/loader/loader.h"
13 13
14//////////////////////////////////////////////////////////////////////////////////////////////////// 14////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,16 +17,11 @@
17namespace FileSys { 17namespace FileSys {
18 18
19/// File system interface to the RomFS archive 19/// File system interface to the RomFS archive
20class Archive_RomFS final : public Archive { 20class Archive_RomFS final : public ArchiveBackend {
21public: 21public:
22 Archive_RomFS(const Loader::AppLoader& app_loader); 22 Archive_RomFS(const Loader::AppLoader& app_loader);
23 ~Archive_RomFS() override;
24 23
25 /** 24 std::string GetName() const override { return "RomFS"; }
26 * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.)
27 * @return IdCode of the archive
28 */
29 IdCode GetIdCode() const override { return IdCode::RomFS; }
30 25
31 /** 26 /**
32 * Open a file specified by its path, using the specified mode 27 * Open a file specified by its path, using the specified mode
@@ -34,67 +29,63 @@ public:
34 * @param mode Mode to open the file with 29 * @param mode Mode to open the file with
35 * @return Opened file, or nullptr 30 * @return Opened file, or nullptr
36 */ 31 */
37 std::unique_ptr<File> OpenFile(const Path& path, const Mode mode) const override; 32 std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
38 33
39 /** 34 /**
40 * Delete a file specified by its path 35 * Delete a file specified by its path
41 * @param path Path relative to the archive 36 * @param path Path relative to the archive
42 * @return Whether the file could be deleted 37 * @return Whether the file could be deleted
43 */ 38 */
44 bool DeleteFile(const FileSys::Path& path) const override; 39 bool DeleteFile(const Path& path) const override;
45
46 /**
47 * Delete a directory specified by its path
48 * @param path Path relative to the archive
49 * @return Whether the directory could be deleted
50 */
51 bool DeleteDirectory(const FileSys::Path& path) const override;
52 40
53 /** 41 /**
54 * Create a directory specified by its path 42 * Rename a File specified by its path
55 * @param path Path relative to the archive 43 * @param src_path Source path relative to the archive
56 * @return Whether the directory could be created 44 * @param dest_path Destination path relative to the archive
45 * @return Whether rename succeeded
57 */ 46 */
58 bool CreateDirectory(const Path& path) const override; 47 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
59 48
60 /** 49 /**
61 * Open a directory specified by its path 50 * Delete a directory specified by its path
62 * @param path Path relative to the archive 51 * @param path Path relative to the archive
63 * @return Opened directory, or nullptr 52 * @return Whether the directory could be deleted
64 */ 53 */
65 std::unique_ptr<Directory> OpenDirectory(const Path& path) const override; 54 bool DeleteDirectory(const Path& path) const override;
66 55
67 /** 56 /**
68 * Read data from the archive 57 * Create a file specified by its path
69 * @param offset Offset in bytes to start reading data from 58 * @param path Path relative to the Archive
70 * @param length Length in bytes of data to read from archive 59 * @param size The size of the new file, filled with zeroes
71 * @param buffer Buffer to read data into 60 * @return File creation result code
72 * @return Number of bytes read
73 */ 61 */
74 size_t Read(const u64 offset, const u32 length, u8* buffer) const override; 62 ResultCode CreateFile(const Path& path, u32 size) const override;
75 63
76 /** 64 /**
77 * Write data to the archive 65 * Create a directory specified by its path
78 * @param offset Offset in bytes to start writing data to 66 * @param path Path relative to the archive
79 * @param length Length in bytes of data to write to archive 67 * @return Whether the directory could be created
80 * @param buffer Buffer to write data from
81 * @param flush The flush parameters (0 == do not flush)
82 * @return Number of bytes written
83 */ 68 */
84 size_t Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) override; 69 bool CreateDirectory(const Path& path) const override;
85 70
86 /** 71 /**
87 * Get the size of the archive in bytes 72 * Rename a Directory specified by its path
88 * @return Size of the archive in bytes 73 * @param src_path Source path relative to the archive
74 * @param dest_path Destination path relative to the archive
75 * @return Whether rename succeeded
89 */ 76 */
90 size_t GetSize() const override; 77 bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
91 78
92 /** 79 /**
93 * Set the size of the archive in bytes 80 * Open a directory specified by its path
81 * @param path Path relative to the archive
82 * @return Opened directory, or nullptr
94 */ 83 */
95 void SetSize(const u64 size) override; 84 std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
96 85
97private: 86private:
87 friend class File_RomFS;
88
98 std::vector<u8> raw_data; 89 std::vector<u8> raw_data;
99}; 90};
100 91
diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp
new file mode 100644
index 000000000..97853567c
--- /dev/null
+++ b/src/core/file_sys/archive_savedata.cpp
@@ -0,0 +1,33 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/archive_savedata.h"
11#include "core/file_sys/disk_archive.h"
12#include "core/settings.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19Archive_SaveData::Archive_SaveData(const std::string& mount_point, u64 program_id)
20 : DiskArchive(mount_point + Common::StringFromFormat("%016X", program_id) + DIR_SEP) {
21 LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str());
22}
23
24bool Archive_SaveData::Initialize() {
25 if (!FileUtil::CreateFullPath(mount_point)) {
26 LOG_ERROR(Service_FS, "Unable to create SaveData path.");
27 return false;
28 }
29
30 return true;
31}
32
33} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h
new file mode 100644
index 000000000..5b0ce29e6
--- /dev/null
+++ b/src/core/file_sys/archive_savedata.h
@@ -0,0 +1,31 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/file_sys/disk_archive.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17/// File system interface to the SaveData archive
18class Archive_SaveData final : public DiskArchive {
19public:
20 Archive_SaveData(const std::string& mount_point, u64 program_id);
21
22 /**
23 * Initialize the archive.
24 * @return true if it initialized successfully
25 */
26 bool Initialize();
27
28 std::string GetName() const override { return "SaveData"; }
29};
30
31} // namespace FileSys
diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp
index c2ffcd40d..1c1c170b6 100644
--- a/src/core/file_sys/archive_sdmc.cpp
+++ b/src/core/file_sys/archive_sdmc.cpp
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <sys/stat.h> 5#include <sys/stat.h>
@@ -8,8 +8,7 @@
8#include "common/file_util.h" 8#include "common/file_util.h"
9 9
10#include "core/file_sys/archive_sdmc.h" 10#include "core/file_sys/archive_sdmc.h"
11#include "core/file_sys/directory_sdmc.h" 11#include "core/file_sys/disk_archive.h"
12#include "core/file_sys/file_sdmc.h"
13#include "core/settings.h" 12#include "core/settings.h"
14 13
15//////////////////////////////////////////////////////////////////////////////////////////////////// 14////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,131 +16,22 @@
17 16
18namespace FileSys { 17namespace FileSys {
19 18
20Archive_SDMC::Archive_SDMC(const std::string& mount_point) { 19Archive_SDMC::Archive_SDMC(const std::string& mount_point) : DiskArchive(mount_point) {
21 this->mount_point = mount_point; 20 LOG_INFO(Service_FS, "Directory %s set as SDMC.", mount_point.c_str());
22 DEBUG_LOG(FILESYS, "Directory %s set as SDMC.", mount_point.c_str());
23} 21}
24 22
25Archive_SDMC::~Archive_SDMC() {
26}
27
28/**
29 * Initialize the archive.
30 * @return true if it initialized successfully
31 */
32bool Archive_SDMC::Initialize() { 23bool Archive_SDMC::Initialize() {
33 if (!Settings::values.use_virtual_sd) { 24 if (!Settings::values.use_virtual_sd) {
34 WARN_LOG(FILESYS, "SDMC disabled by config."); 25 LOG_WARNING(Service_FS, "SDMC disabled by config.");
35 return false; 26 return false;
36 } 27 }
37 28
38 if (!FileUtil::CreateFullPath(mount_point)) { 29 if (!FileUtil::CreateFullPath(mount_point)) {
39 WARN_LOG(FILESYS, "Unable to create SDMC path."); 30 LOG_ERROR(Service_FS, "Unable to create SDMC path.");
40 return false; 31 return false;
41 } 32 }
42 33
43 return true; 34 return true;
44} 35}
45 36
46/**
47 * Open a file specified by its path, using the specified mode
48 * @param path Path relative to the archive
49 * @param mode Mode to open the file with
50 * @return Opened file, or nullptr
51 */
52std::unique_ptr<File> Archive_SDMC::OpenFile(const Path& path, const Mode mode) const {
53 DEBUG_LOG(FILESYS, "called path=%s mode=%d", path.DebugStr().c_str(), mode);
54 File_SDMC* file = new File_SDMC(this, path, mode);
55 if (!file->Open())
56 return nullptr;
57 return std::unique_ptr<File>(file);
58}
59
60/**
61 * Delete a file specified by its path
62 * @param path Path relative to the archive
63 * @return Whether the file could be deleted
64 */
65bool Archive_SDMC::DeleteFile(const FileSys::Path& path) const {
66 return FileUtil::Delete(GetMountPoint() + path.AsString());
67}
68
69/**
70 * Delete a directory specified by its path
71 * @param path Path relative to the archive
72 * @return Whether the directory could be deleted
73 */
74bool Archive_SDMC::DeleteDirectory(const FileSys::Path& path) const {
75 return FileUtil::DeleteDir(GetMountPoint() + path.AsString());
76}
77
78/**
79 * Create a directory specified by its path
80 * @param path Path relative to the archive
81 * @return Whether the directory could be created
82 */
83bool Archive_SDMC::CreateDirectory(const Path& path) const {
84 return FileUtil::CreateDir(GetMountPoint() + path.AsString());
85}
86
87/**
88 * Open a directory specified by its path
89 * @param path Path relative to the archive
90 * @return Opened directory, or nullptr
91 */
92std::unique_ptr<Directory> Archive_SDMC::OpenDirectory(const Path& path) const {
93 DEBUG_LOG(FILESYS, "called path=%s", path.DebugStr().c_str());
94 Directory_SDMC* directory = new Directory_SDMC(this, path);
95 return std::unique_ptr<Directory>(directory);
96}
97
98/**
99 * Read data from the archive
100 * @param offset Offset in bytes to start reading archive from
101 * @param length Length in bytes to read data from archive
102 * @param buffer Buffer to read data into
103 * @return Number of bytes read
104 */
105size_t Archive_SDMC::Read(const u64 offset, const u32 length, u8* buffer) const {
106 ERROR_LOG(FILESYS, "(UNIMPLEMENTED)");
107 return -1;
108}
109
110/**
111 * Write data to the archive
112 * @param offset Offset in bytes to start writing data to
113 * @param length Length in bytes of data to write to archive
114 * @param buffer Buffer to write data from
115 * @param flush The flush parameters (0 == do not flush)
116 * @return Number of bytes written
117 */
118size_t Archive_SDMC::Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) {
119 ERROR_LOG(FILESYS, "(UNIMPLEMENTED)");
120 return -1;
121}
122
123/**
124 * Get the size of the archive in bytes
125 * @return Size of the archive in bytes
126 */
127size_t Archive_SDMC::GetSize() const {
128 ERROR_LOG(FILESYS, "(UNIMPLEMENTED)");
129 return 0;
130}
131
132/**
133 * Set the size of the archive in bytes
134 */
135void Archive_SDMC::SetSize(const u64 size) {
136 ERROR_LOG(FILESYS, "(UNIMPLEMENTED)");
137}
138
139/**
140 * Getter for the path used for this Archive
141 * @return Mount point of that passthrough archive
142 */
143std::string Archive_SDMC::GetMountPoint() const {
144 return mount_point;
145}
146
147} // namespace FileSys 37} // namespace FileSys
diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h
index 74ce29c0d..1b801f217 100644
--- a/src/core/file_sys/archive_sdmc.h
+++ b/src/core/file_sys/archive_sdmc.h
@@ -1,12 +1,12 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9#include "core/file_sys/archive.h" 9#include "core/file_sys/disk_archive.h"
10#include "core/loader/loader.h" 10#include "core/loader/loader.h"
11 11
12//////////////////////////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -15,10 +15,9 @@
15namespace FileSys { 15namespace FileSys {
16 16
17/// File system interface to the SDMC archive 17/// File system interface to the SDMC archive
18class Archive_SDMC final : public Archive { 18class Archive_SDMC final : public DiskArchive {
19public: 19public:
20 Archive_SDMC(const std::string& mount_point); 20 Archive_SDMC(const std::string& mount_point);
21 ~Archive_SDMC() override;
22 21
23 /** 22 /**
24 * Initialize the archive. 23 * Initialize the archive.
@@ -26,86 +25,7 @@ public:
26 */ 25 */
27 bool Initialize(); 26 bool Initialize();
28 27
29 /** 28 std::string GetName() const override { return "SDMC"; }
30 * Get the IdCode of the archive (e.g. RomFS, SaveData, etc.)
31 * @return IdCode of the archive
32 */
33 IdCode GetIdCode() const override { return IdCode::SDMC; }
34
35 /**
36 * Open a file specified by its path, using the specified mode
37 * @param path Path relative to the archive
38 * @param mode Mode to open the file with
39 * @return Opened file, or nullptr
40 */
41 std::unique_ptr<File> OpenFile(const Path& path, const Mode mode) const override;
42
43 /**
44 * Delete a file specified by its path
45 * @param path Path relative to the archive
46 * @return Whether the file could be deleted
47 */
48 bool DeleteFile(const FileSys::Path& path) const override;
49
50 /**
51 * Delete a directory specified by its path
52 * @param path Path relative to the archive
53 * @return Whether the directory could be deleted
54 */
55 bool DeleteDirectory(const FileSys::Path& path) const override;
56
57 /**
58 * Create a directory specified by its path
59 * @param path Path relative to the archive
60 * @return Whether the directory could be created
61 */
62 bool CreateDirectory(const Path& path) const override;
63
64 /**
65 * Open a directory specified by its path
66 * @param path Path relative to the archive
67 * @return Opened directory, or nullptr
68 */
69 std::unique_ptr<Directory> OpenDirectory(const Path& path) const override;
70
71 /**
72 * Read data from the archive
73 * @param offset Offset in bytes to start reading archive from
74 * @param length Length in bytes to read data from archive
75 * @param buffer Buffer to read data into
76 * @return Number of bytes read
77 */
78 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
79
80 /**
81 * Write data to the archive
82 * @param offset Offset in bytes to start writing data to
83 * @param length Length in bytes of data to write to archive
84 * @param buffer Buffer to write data from
85 * @param flush The flush parameters (0 == do not flush)
86 * @return Number of bytes written
87 */
88 size_t Write(const u64 offset, const u32 length, const u32 flush, u8* buffer) override;
89
90 /**
91 * Get the size of the archive in bytes
92 * @return Size of the archive in bytes
93 */
94 size_t GetSize() const override;
95
96 /**
97 * Set the size of the archive in bytes
98 */
99 void SetSize(const u64 size) override;
100
101 /**
102 * Getter for the path used for this Archive
103 * @return Mount point of that passthrough archive
104 */
105 std::string GetMountPoint() const;
106
107private:
108 std::string mount_point;
109}; 29};
110 30
111} // namespace FileSys 31} // namespace FileSys
diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp
new file mode 100644
index 000000000..0da32d510
--- /dev/null
+++ b/src/core/file_sys/archive_systemsavedata.cpp
@@ -0,0 +1,39 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/archive_systemsavedata.h"
11#include "core/file_sys/disk_archive.h"
12#include "core/settings.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19static std::string GetSystemSaveDataPath(const std::string& mount_point, u64 save_id) {
20 u32 save_high = static_cast<u32>((save_id >> 32) & 0xFFFFFFFF);
21 u32 save_low = static_cast<u32>(save_id & 0xFFFFFFFF);
22 return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_low, save_high);
23}
24
25Archive_SystemSaveData::Archive_SystemSaveData(const std::string& mount_point, u64 save_id)
26 : DiskArchive(GetSystemSaveDataPath(mount_point, save_id)) {
27 LOG_INFO(Service_FS, "Directory %s set as SystemSaveData.", this->mount_point.c_str());
28}
29
30bool Archive_SystemSaveData::Initialize() {
31 if (!FileUtil::CreateFullPath(mount_point)) {
32 LOG_ERROR(Service_FS, "Unable to create SystemSaveData path.");
33 return false;
34 }
35
36 return true;
37}
38
39} // namespace FileSys
diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h
new file mode 100644
index 000000000..55d85193c
--- /dev/null
+++ b/src/core/file_sys/archive_systemsavedata.h
@@ -0,0 +1,33 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/file_sys/disk_archive.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17/// File system interface to the SystemSaveData archive
18/// TODO(Subv): This archive should point to a location in the NAND,
19/// specifically nand:/data/<ID0>/sysdata/<SaveID-Low>/<SaveID-High>
20class Archive_SystemSaveData final : public DiskArchive {
21public:
22 Archive_SystemSaveData(const std::string& mount_point, u64 save_id);
23
24 /**
25 * Initialize the archive.
26 * @return true if it initialized successfully
27 */
28 bool Initialize();
29
30 std::string GetName() const override { return "SystemSaveData"; }
31};
32
33} // namespace FileSys
diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory_backend.h
index e10431337..7f327dc42 100644
--- a/src/core/file_sys/directory.h
+++ b/src/core/file_sys/directory_backend.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
@@ -36,10 +36,16 @@ static_assert(offsetof(Entry, extension) == 0x216, "Wrong offset for extension i
36static_assert(offsetof(Entry, is_archive) == 0x21E, "Wrong offset for is_archive in Entry."); 36static_assert(offsetof(Entry, is_archive) == 0x21E, "Wrong offset for is_archive in Entry.");
37static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size in Entry."); 37static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size in Entry.");
38 38
39class Directory : NonCopyable { 39class DirectoryBackend : NonCopyable {
40public: 40public:
41 Directory() { } 41 DirectoryBackend() { }
42 virtual ~Directory() { } 42 virtual ~DirectoryBackend() { }
43
44 /**
45 * Open the directory
46 * @return true if the directory opened correctly
47 */
48 virtual bool Open() = 0;
43 49
44 /** 50 /**
45 * List files contained in the directory 51 * List files contained in the directory
diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp
index 4e8f4c04d..e130aca17 100644
--- a/src/core/file_sys/directory_romfs.cpp
+++ b/src/core/file_sys/directory_romfs.cpp
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
@@ -17,20 +17,14 @@ Directory_RomFS::Directory_RomFS() {
17Directory_RomFS::~Directory_RomFS() { 17Directory_RomFS::~Directory_RomFS() {
18} 18}
19 19
20/** 20bool Directory_RomFS::Open() {
21 * List files contained in the directory 21 return false;
22 * @param count Number of entries to return at once in entries 22}
23 * @param entries Buffer to read data into 23
24 * @return Number of entries listed
25 */
26u32 Directory_RomFS::Read(const u32 count, Entry* entries) { 24u32 Directory_RomFS::Read(const u32 count, Entry* entries) {
27 return 0; 25 return 0;
28} 26}
29 27
30/**
31 * Close the directory
32 * @return true if the directory closed correctly
33 */
34bool Directory_RomFS::Close() const { 28bool Directory_RomFS::Close() const {
35 return false; 29 return false;
36} 30}
diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h
index 4b71c4b13..2297f1645 100644
--- a/src/core/file_sys/directory_romfs.h
+++ b/src/core/file_sys/directory_romfs.h
@@ -1,12 +1,12 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9#include "core/file_sys/directory.h" 9#include "core/file_sys/directory_backend.h"
10#include "core/loader/loader.h" 10#include "core/loader/loader.h"
11 11
12//////////////////////////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -14,12 +14,18 @@
14 14
15namespace FileSys { 15namespace FileSys {
16 16
17class Directory_RomFS final : public Directory { 17class Directory_RomFS final : public DirectoryBackend {
18public: 18public:
19 Directory_RomFS(); 19 Directory_RomFS();
20 ~Directory_RomFS() override; 20 ~Directory_RomFS() override;
21 21
22 /** 22 /**
23 * Open the directory
24 * @return true if the directory opened correctly
25 */
26 bool Open() override;
27
28 /**
23 * List files contained in the directory 29 * List files contained in the directory
24 * @param count Number of entries to return at once in entries 30 * @param count Number of entries to return at once in entries
25 * @param entries Buffer to read data into 31 * @param entries Buffer to read data into
diff --git a/src/core/file_sys/directory_sdmc.cpp b/src/core/file_sys/directory_sdmc.cpp
deleted file mode 100644
index 60a197ce9..000000000
--- a/src/core/file_sys/directory_sdmc.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/directory_sdmc.h"
11#include "core/file_sys/archive_sdmc.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18Directory_SDMC::Directory_SDMC(const Archive_SDMC* archive, const Path& path) {
19 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
20 // the root directory we set while opening the archive.
21 // For example, opening /../../usr/bin can give the emulated program your installed programs.
22 std::string absolute_path = archive->GetMountPoint() + path.AsString();
23 FileUtil::ScanDirectoryTree(absolute_path, directory);
24 children_iterator = directory.children.begin();
25}
26
27Directory_SDMC::~Directory_SDMC() {
28 Close();
29}
30
31/**
32 * List files contained in the directory
33 * @param count Number of entries to return at once in entries
34 * @param entries Buffer to read data into
35 * @return Number of entries listed
36 */
37u32 Directory_SDMC::Read(const u32 count, Entry* entries) {
38 u32 entries_read = 0;
39
40 while (entries_read < count && children_iterator != directory.children.cend()) {
41 const FileUtil::FSTEntry& file = *children_iterator;
42 const std::string& filename = file.virtualName;
43 Entry& entry = entries[entries_read];
44
45 WARN_LOG(FILESYS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, file.isDirectory);
46
47 // TODO(Link Mauve): use a proper conversion to UTF-16.
48 for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
49 entry.filename[j] = filename[j];
50 if (!filename[j])
51 break;
52 }
53
54 FileUtil::SplitFilename83(filename, entry.short_name, entry.extension);
55
56 entry.is_directory = file.isDirectory;
57 entry.is_hidden = (filename[0] == '.');
58 entry.is_read_only = 0;
59 entry.file_size = file.size;
60
61 // We emulate a SD card where the archive bit has never been cleared, as it would be on
62 // most user SD cards.
63 // Some homebrews (blargSNES for instance) are known to mistakenly use the archive bit as a
64 // file bit.
65 entry.is_archive = !file.isDirectory;
66
67 ++entries_read;
68 ++children_iterator;
69 }
70 return entries_read;
71}
72
73/**
74 * Close the directory
75 * @return true if the directory closed correctly
76 */
77bool Directory_SDMC::Close() const {
78 return true;
79}
80
81} // namespace FileSys
diff --git a/src/core/file_sys/directory_sdmc.h b/src/core/file_sys/directory_sdmc.h
deleted file mode 100644
index 4520d0401..000000000
--- a/src/core/file_sys/directory_sdmc.h
+++ /dev/null
@@ -1,48 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/directory.h"
11#include "core/file_sys/archive_sdmc.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19class Directory_SDMC final : public Directory {
20public:
21 Directory_SDMC();
22 Directory_SDMC(const Archive_SDMC* archive, const Path& path);
23 ~Directory_SDMC() override;
24
25 /**
26 * List files contained in the directory
27 * @param count Number of entries to return at once in entries
28 * @param entries Buffer to read data into
29 * @return Number of entries listed
30 */
31 u32 Read(const u32 count, Entry* entries) override;
32
33 /**
34 * Close the directory
35 * @return true if the directory closed correctly
36 */
37 bool Close() const override;
38
39private:
40 u32 total_entries_in_directory;
41 FileUtil::FSTEntry directory;
42
43 // We need to remember the last entry we returned, so a subsequent call to Read will continue
44 // from the next one. This iterator will always point to the next unread entry.
45 std::vector<FileUtil::FSTEntry>::iterator children_iterator;
46};
47
48} // namespace FileSys
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
new file mode 100644
index 000000000..0197f727d
--- /dev/null
+++ b/src/core/file_sys/disk_archive.cpp
@@ -0,0 +1,188 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/disk_archive.h"
11#include "core/settings.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const {
19 LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
20 DiskFile* file = new DiskFile(this, path, mode);
21 if (!file->Open())
22 return nullptr;
23 return std::unique_ptr<FileBackend>(file);
24}
25
26bool DiskArchive::DeleteFile(const Path& path) const {
27 return FileUtil::Delete(GetMountPoint() + path.AsString());
28}
29
30bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
31 return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString());
32}
33
34bool DiskArchive::DeleteDirectory(const Path& path) const {
35 return FileUtil::DeleteDir(GetMountPoint() + path.AsString());
36}
37
38ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u32 size) const {
39 std::string full_path = GetMountPoint() + path.AsString();
40
41 if (FileUtil::Exists(full_path))
42 return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::FS, ErrorSummary::NothingHappened, ErrorLevel::Info);
43
44 if (size == 0) {
45 FileUtil::CreateEmptyFile(full_path);
46 return RESULT_SUCCESS;
47 }
48
49 FileUtil::IOFile file(full_path, "wb");
50 // Creates a sparse file (or a normal file on filesystems without the concept of sparse files)
51 // We do this by seeking to the right size, then writing a single null byte.
52 if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1)
53 return RESULT_SUCCESS;
54
55 return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource, ErrorLevel::Info);
56}
57
58
59bool DiskArchive::CreateDirectory(const Path& path) const {
60 return FileUtil::CreateDir(GetMountPoint() + path.AsString());
61}
62
63bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
64 return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString());
65}
66
67std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const {
68 LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str());
69 DiskDirectory* directory = new DiskDirectory(this, path);
70 if (!directory->Open())
71 return nullptr;
72 return std::unique_ptr<DirectoryBackend>(directory);
73}
74
75////////////////////////////////////////////////////////////////////////////////////////////////////
76
77DiskFile::DiskFile(const DiskArchive* archive, const Path& path, const Mode mode) {
78 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
79 // the root directory we set while opening the archive.
80 // For example, opening /../../etc/passwd can give the emulated program your users list.
81 this->path = archive->GetMountPoint() + path.AsString();
82 this->mode.hex = mode.hex;
83 this->archive = archive;
84}
85
86bool DiskFile::Open() {
87 if (!mode.create_flag && !FileUtil::Exists(path)) {
88 LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str());
89 return false;
90 }
91
92 std::string mode_string;
93 if (mode.create_flag)
94 mode_string = "w+";
95 else if (mode.write_flag)
96 mode_string = "r+"; // Files opened with Write access can be read from
97 else if (mode.read_flag)
98 mode_string = "r";
99
100 // Open the file in binary mode, to avoid problems with CR/LF on Windows systems
101 mode_string += "b";
102
103 file = new FileUtil::IOFile(path, mode_string.c_str());
104 return true;
105}
106
107size_t DiskFile::Read(const u64 offset, const u32 length, u8* buffer) const {
108 file->Seek(offset, SEEK_SET);
109 return file->ReadBytes(buffer, length);
110}
111
112size_t DiskFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
113 file->Seek(offset, SEEK_SET);
114 size_t written = file->WriteBytes(buffer, length);
115 if (flush)
116 file->Flush();
117 return written;
118}
119
120size_t DiskFile::GetSize() const {
121 return static_cast<size_t>(file->GetSize());
122}
123
124bool DiskFile::SetSize(const u64 size) const {
125 file->Resize(size);
126 file->Flush();
127 return true;
128}
129
130bool DiskFile::Close() const {
131 return file->Close();
132}
133
134////////////////////////////////////////////////////////////////////////////////////////////////////
135
136DiskDirectory::DiskDirectory(const DiskArchive* archive, const Path& path) {
137 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
138 // the root directory we set while opening the archive.
139 // For example, opening /../../usr/bin can give the emulated program your installed programs.
140 this->path = archive->GetMountPoint() + path.AsString();
141 this->archive = archive;
142}
143
144bool DiskDirectory::Open() {
145 if (!FileUtil::IsDirectory(path))
146 return false;
147 FileUtil::ScanDirectoryTree(path, directory);
148 children_iterator = directory.children.begin();
149 return true;
150}
151
152u32 DiskDirectory::Read(const u32 count, Entry* entries) {
153 u32 entries_read = 0;
154
155 while (entries_read < count && children_iterator != directory.children.cend()) {
156 const FileUtil::FSTEntry& file = *children_iterator;
157 const std::string& filename = file.virtualName;
158 Entry& entry = entries[entries_read];
159
160 LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, file.isDirectory);
161
162 // TODO(Link Mauve): use a proper conversion to UTF-16.
163 for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
164 entry.filename[j] = filename[j];
165 if (!filename[j])
166 break;
167 }
168
169 FileUtil::SplitFilename83(filename, entry.short_name, entry.extension);
170
171 entry.is_directory = file.isDirectory;
172 entry.is_hidden = (filename[0] == '.');
173 entry.is_read_only = 0;
174 entry.file_size = file.size;
175
176 // We emulate a SD card where the archive bit has never been cleared, as it would be on
177 // most user SD cards.
178 // Some homebrews (blargSNES for instance) are known to mistakenly use the archive bit as a
179 // file bit.
180 entry.is_archive = !file.isDirectory;
181
182 ++entries_read;
183 ++children_iterator;
184 }
185 return entries_read;
186}
187
188} // namespace FileSys
diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h
new file mode 100644
index 000000000..018ebd2ed
--- /dev/null
+++ b/src/core/file_sys/disk_archive.h
@@ -0,0 +1,103 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/archive_backend.h"
11#include "core/loader/loader.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18/**
19 * Helper which implements a backend accessing the host machine's filesystem.
20 * This should be subclassed by concrete archive types, which will provide the
21 * base directory on the host filesystem and override any required functionality.
22 */
23class DiskArchive : public ArchiveBackend {
24public:
25 DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {}
26
27 virtual std::string GetName() const = 0;
28 std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
29 bool DeleteFile(const Path& path) const override;
30 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
31 bool DeleteDirectory(const Path& path) const override;
32 ResultCode CreateFile(const Path& path, u32 size) const override;
33 bool CreateDirectory(const Path& path) const override;
34 bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
35 std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
36
37 /**
38 * Getter for the path used for this Archive
39 * @return Mount point of that passthrough archive
40 */
41 const std::string& GetMountPoint() const {
42 return mount_point;
43 }
44
45protected:
46 std::string mount_point;
47};
48
49class DiskFile : public FileBackend {
50public:
51 DiskFile();
52 DiskFile(const DiskArchive* archive, const Path& path, const Mode mode);
53
54 ~DiskFile() override {
55 Close();
56 }
57
58 bool Open() override;
59 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
60 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
61 size_t GetSize() const override;
62 bool SetSize(const u64 size) const override;
63 bool Close() const override;
64
65 void Flush() const override {
66 file->Flush();
67 }
68
69protected:
70 const DiskArchive* archive;
71 std::string path;
72 Mode mode;
73 FileUtil::IOFile* file;
74};
75
76class DiskDirectory : public DirectoryBackend {
77public:
78 DiskDirectory();
79 DiskDirectory(const DiskArchive* archive, const Path& path);
80
81 ~DiskDirectory() override {
82 Close();
83 }
84
85 bool Open() override;
86 u32 Read(const u32 count, Entry* entries) override;
87
88 bool Close() const override {
89 return true;
90 }
91
92protected:
93 const DiskArchive* archive;
94 std::string path;
95 u32 total_entries_in_directory;
96 FileUtil::FSTEntry directory;
97
98 // We need to remember the last entry we returned, so a subsequent call to Read will continue
99 // from the next one. This iterator will always point to the next unread entry.
100 std::vector<FileUtil::FSTEntry>::iterator children_iterator;
101};
102
103} // namespace FileSys
diff --git a/src/core/file_sys/file.h b/src/core/file_sys/file_backend.h
index 4013b6c3e..35890af1f 100644
--- a/src/core/file_sys/file.h
+++ b/src/core/file_sys/file_backend.h
@@ -1,5 +1,5 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
@@ -13,10 +13,10 @@
13 13
14namespace FileSys { 14namespace FileSys {
15 15
16class File : NonCopyable { 16class FileBackend : NonCopyable {
17public: 17public:
18 File() { } 18 FileBackend() { }
19 virtual ~File() { } 19 virtual ~FileBackend() { }
20 20
21 /** 21 /**
22 * Open the file 22 * Open the file
@@ -61,6 +61,11 @@ public:
61 * @return true if the file closed correctly 61 * @return true if the file closed correctly
62 */ 62 */
63 virtual bool Close() const = 0; 63 virtual bool Close() const = 0;
64
65 /**
66 * Flushes the file
67 */
68 virtual void Flush() const = 0;
64}; 69};
65 70
66} // namespace FileSys 71} // namespace FileSys
diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp
index b55708df4..7467d6d31 100644
--- a/src/core/file_sys/file_romfs.cpp
+++ b/src/core/file_sys/file_romfs.cpp
@@ -1,74 +1,41 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6 6
7#include "core/file_sys/file_romfs.h" 7#include "core/file_sys/file_romfs.h"
8#include "core/file_sys/archive_romfs.h"
8 9
9//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
10// FileSys namespace 11// FileSys namespace
11 12
12namespace FileSys { 13namespace FileSys {
13 14
14File_RomFS::File_RomFS() {
15}
16
17File_RomFS::~File_RomFS() {
18}
19
20/**
21 * Open the file
22 * @return true if the file opened correctly
23 */
24bool File_RomFS::Open() { 15bool File_RomFS::Open() {
25 return false; 16 return true;
26} 17}
27 18
28/**
29 * Read data from the file
30 * @param offset Offset in bytes to start reading data from
31 * @param length Length in bytes of data to read from file
32 * @param buffer Buffer to read data into
33 * @return Number of bytes read
34 */
35size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { 19size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
36 return -1; 20 LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
21 memcpy(buffer, &archive->raw_data[(u32)offset], length);
22 return length;
37} 23}
38 24
39/**
40 * Write data to the file
41 * @param offset Offset in bytes to start writing data to
42 * @param length Length in bytes of data to write to file
43 * @param flush The flush parameters (0 == do not flush)
44 * @param buffer Buffer to read data from
45 * @return Number of bytes written
46 */
47size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { 25size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
48 return -1; 26 LOG_WARNING(Service_FS, "Attempted to write to ROMFS.");
27 return 0;
49} 28}
50 29
51/**
52 * Get the size of the file in bytes
53 * @return Size of the file in bytes
54 */
55size_t File_RomFS::GetSize() const { 30size_t File_RomFS::GetSize() const {
56 return -1; 31 return sizeof(u8) * archive->raw_data.size();
57} 32}
58 33
59/**
60 * Set the size of the file in bytes
61 * @param size New size of the file
62 * @return true if successful
63 */
64bool File_RomFS::SetSize(const u64 size) const { 34bool File_RomFS::SetSize(const u64 size) const {
35 LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS");
65 return false; 36 return false;
66} 37}
67 38
68/**
69 * Close the file
70 * @return true if the file closed correctly
71 */
72bool File_RomFS::Close() const { 39bool File_RomFS::Close() const {
73 return false; 40 return false;
74} 41}
diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h
index 5196701d3..04d8a16a2 100644
--- a/src/core/file_sys/file_romfs.h
+++ b/src/core/file_sys/file_romfs.h
@@ -1,12 +1,12 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9#include "core/file_sys/file.h" 9#include "core/file_sys/file_backend.h"
10#include "core/loader/loader.h" 10#include "core/loader/loader.h"
11 11
12//////////////////////////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -14,10 +14,11 @@
14 14
15namespace FileSys { 15namespace FileSys {
16 16
17class File_RomFS final : public File { 17class Archive_RomFS;
18
19class File_RomFS final : public FileBackend {
18public: 20public:
19 File_RomFS(); 21 File_RomFS(const Archive_RomFS* archive) : archive(archive) {}
20 ~File_RomFS() override;
21 22
22 /** 23 /**
23 * Open the file 24 * Open the file
@@ -62,6 +63,11 @@ public:
62 * @return true if the file closed correctly 63 * @return true if the file closed correctly
63 */ 64 */
64 bool Close() const override; 65 bool Close() const override;
66
67 void Flush() const override { }
68
69private:
70 const Archive_RomFS* archive;
65}; 71};
66 72
67} // namespace FileSys 73} // namespace FileSys
diff --git a/src/core/file_sys/file_sdmc.cpp b/src/core/file_sys/file_sdmc.cpp
deleted file mode 100644
index a4b90670a..000000000
--- a/src/core/file_sys/file_sdmc.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/file_sdmc.h"
11#include "core/file_sys/archive_sdmc.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18File_SDMC::File_SDMC(const Archive_SDMC* archive, const Path& path, const Mode mode) {
19 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
20 // the root directory we set while opening the archive.
21 // For example, opening /../../etc/passwd can give the emulated program your users list.
22 this->path = archive->GetMountPoint() + path.AsString();
23 this->mode.hex = mode.hex;
24}
25
26File_SDMC::~File_SDMC() {
27 Close();
28}
29
30/**
31 * Open the file
32 * @return true if the file opened correctly
33 */
34bool File_SDMC::Open() {
35 if (!mode.create_flag && !FileUtil::Exists(path)) {
36 ERROR_LOG(FILESYS, "Non-existing file %s can’t be open without mode create.", path.c_str());
37 return false;
38 }
39
40 std::string mode_string;
41 if (mode.read_flag && mode.write_flag)
42 mode_string = "w+";
43 else if (mode.read_flag)
44 mode_string = "r";
45 else if (mode.write_flag)
46 mode_string = "w";
47
48 file = new FileUtil::IOFile(path, mode_string.c_str());
49 return true;
50}
51
52/**
53 * Read data from the file
54 * @param offset Offset in bytes to start reading data from
55 * @param length Length in bytes of data to read from file
56 * @param buffer Buffer to read data into
57 * @return Number of bytes read
58 */
59size_t File_SDMC::Read(const u64 offset, const u32 length, u8* buffer) const {
60 file->Seek(offset, SEEK_SET);
61 return file->ReadBytes(buffer, length);
62}
63
64/**
65 * Write data to the file
66 * @param offset Offset in bytes to start writing data to
67 * @param length Length in bytes of data to write to file
68 * @param flush The flush parameters (0 == do not flush)
69 * @param buffer Buffer to read data from
70 * @return Number of bytes written
71 */
72size_t File_SDMC::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
73 file->Seek(offset, SEEK_SET);
74 size_t written = file->WriteBytes(buffer, length);
75 if (flush)
76 file->Flush();
77 return written;
78}
79
80/**
81 * Get the size of the file in bytes
82 * @return Size of the file in bytes
83 */
84size_t File_SDMC::GetSize() const {
85 return static_cast<size_t>(file->GetSize());
86}
87
88/**
89 * Set the size of the file in bytes
90 * @param size New size of the file
91 * @return true if successful
92 */
93bool File_SDMC::SetSize(const u64 size) const {
94 file->Resize(size);
95 file->Flush();
96 return true;
97}
98
99/**
100 * Close the file
101 * @return true if the file closed correctly
102 */
103bool File_SDMC::Close() const {
104 return file->Close();
105}
106
107} // namespace FileSys
diff --git a/src/core/file_sys/file_sdmc.h b/src/core/file_sys/file_sdmc.h
deleted file mode 100644
index 80b445968..000000000
--- a/src/core/file_sys/file_sdmc.h
+++ /dev/null
@@ -1,75 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/file.h"
11#include "core/file_sys/archive_sdmc.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19class File_SDMC final : public File {
20public:
21 File_SDMC();
22 File_SDMC(const Archive_SDMC* archive, const Path& path, const Mode mode);
23 ~File_SDMC() override;
24
25 /**
26 * Open the file
27 * @return true if the file opened correctly
28 */
29 bool Open() override;
30
31 /**
32 * Read data from the file
33 * @param offset Offset in bytes to start reading data from
34 * @param length Length in bytes of data to read from file
35 * @param buffer Buffer to read data into
36 * @return Number of bytes read
37 */
38 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
39
40 /**
41 * Write data to the file
42 * @param offset Offset in bytes to start writing data to
43 * @param length Length in bytes of data to write to file
44 * @param flush The flush parameters (0 == do not flush)
45 * @param buffer Buffer to read data from
46 * @return Number of bytes written
47 */
48 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
49
50 /**
51 * Get the size of the file in bytes
52 * @return Size of the file in bytes
53 */
54 size_t GetSize() const override;
55
56 /**
57 * Set the size of the file in bytes
58 * @param size New size of the file
59 * @return true if successful
60 */
61 bool SetSize(const u64 size) const override;
62
63 /**
64 * Close the file
65 * @return true if the file closed correctly
66 */
67 bool Close() const override;
68
69private:
70 std::string path;
71 Mode mode;
72 FileUtil::IOFile* file;
73};
74
75} // namespace FileSys