summaryrefslogtreecommitdiff
path: root/src/core/file_sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/archive_backend.cpp35
-rw-r--r--src/core/file_sys/archive_backend.h33
-rw-r--r--src/core/file_sys/archive_extsavedata.cpp23
-rw-r--r--src/core/file_sys/archive_extsavedata.h16
-rw-r--r--src/core/file_sys/archive_romfs.cpp9
-rw-r--r--src/core/file_sys/archive_romfs.h6
-rw-r--r--src/core/file_sys/archive_savedata.cpp40
-rw-r--r--src/core/file_sys/archive_savedata.h5
-rw-r--r--src/core/file_sys/archive_savedatacheck.cpp18
-rw-r--r--src/core/file_sys/archive_savedatacheck.h5
-rw-r--r--src/core/file_sys/archive_sdmc.cpp8
-rw-r--r--src/core/file_sys/archive_sdmc.h5
-rw-r--r--src/core/file_sys/archive_systemsavedata.cpp12
-rw-r--r--src/core/file_sys/archive_systemsavedata.h9
-rw-r--r--src/core/file_sys/directory_backend.h20
-rw-r--r--src/core/file_sys/disk_archive.cpp51
-rw-r--r--src/core/file_sys/disk_archive.h9
-rw-r--r--src/core/file_sys/file_backend.h8
-rw-r--r--src/core/file_sys/ivfc_archive.cpp36
-rw-r--r--src/core/file_sys/ivfc_archive.h27
20 files changed, 204 insertions, 171 deletions
diff --git a/src/core/file_sys/archive_backend.cpp b/src/core/file_sys/archive_backend.cpp
index cc0aa7022..1fae0ede0 100644
--- a/src/core/file_sys/archive_backend.cpp
+++ b/src/core/file_sys/archive_backend.cpp
@@ -5,34 +5,28 @@
5#include <cstddef> 5#include <cstddef>
6#include <iomanip> 6#include <iomanip>
7#include <sstream> 7#include <sstream>
8
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10#include "common/string_util.h" 9#include "common/string_util.h"
11
12#include "core/file_sys/archive_backend.h" 10#include "core/file_sys/archive_backend.h"
13#include "core/memory.h" 11#include "core/memory.h"
14 12
15
16namespace FileSys { 13namespace FileSys {
17 14
18Path::Path(LowPathType type, u32 size, u32 pointer) : type(type) { 15Path::Path(LowPathType type, u32 size, u32 pointer) : type(type) {
19 switch (type) { 16 switch (type) {
20 case Binary: 17 case Binary: {
21 {
22 binary.resize(size); 18 binary.resize(size);
23 Memory::ReadBlock(pointer, binary.data(), binary.size()); 19 Memory::ReadBlock(pointer, binary.data(), binary.size());
24 break; 20 break;
25 } 21 }
26 22
27 case Char: 23 case Char: {
28 {
29 string.resize(size - 1); // Data is always null-terminated. 24 string.resize(size - 1); // Data is always null-terminated.
30 Memory::ReadBlock(pointer, &string[0], string.size()); 25 Memory::ReadBlock(pointer, &string[0], string.size());
31 break; 26 break;
32 } 27 }
33 28
34 case Wchar: 29 case Wchar: {
35 {
36 u16str.resize(size / 2 - 1); // Data is always null-terminated. 30 u16str.resize(size / 2 - 1); // Data is always null-terminated.
37 Memory::ReadBlock(pointer, &u16str[0], u16str.size() * sizeof(char16_t)); 31 Memory::ReadBlock(pointer, &u16str[0], u16str.size() * sizeof(char16_t));
38 break; 32 break;
@@ -50,8 +44,7 @@ std::string Path::DebugStr() const {
50 return "[Invalid]"; 44 return "[Invalid]";
51 case Empty: 45 case Empty:
52 return "[Empty]"; 46 return "[Empty]";
53 case Binary: 47 case Binary: {
54 {
55 std::stringstream res; 48 std::stringstream res;
56 res << "[Binary: "; 49 res << "[Binary: ";
57 for (unsigned byte : binary) 50 for (unsigned byte : binary)
@@ -73,13 +66,13 @@ std::string Path::AsString() const {
73 case Wchar: 66 case Wchar:
74 return Common::UTF16ToUTF8(u16str); 67 return Common::UTF16ToUTF8(u16str);
75 case Empty: 68 case Empty:
76 return{}; 69 return {};
77 case Invalid: 70 case Invalid:
78 case Binary: 71 case Binary:
79 default: 72 default:
80 // TODO(yuriks): Add assert 73 // TODO(yuriks): Add assert
81 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); 74 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
82 return{}; 75 return {};
83 } 76 }
84} 77}
85 78
@@ -90,12 +83,12 @@ std::u16string Path::AsU16Str() const {
90 case Wchar: 83 case Wchar:
91 return u16str; 84 return u16str;
92 case Empty: 85 case Empty:
93 return{}; 86 return {};
94 case Invalid: 87 case Invalid:
95 case Binary: 88 case Binary:
96 // TODO(yuriks): Add assert 89 // TODO(yuriks): Add assert
97 LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); 90 LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
98 return{}; 91 return {};
99 } 92 }
100} 93}
101 94
@@ -105,25 +98,23 @@ std::vector<u8> Path::AsBinary() const {
105 return binary; 98 return binary;
106 case Char: 99 case Char:
107 return std::vector<u8>(string.begin(), string.end()); 100 return std::vector<u8>(string.begin(), string.end());
108 case Wchar: 101 case Wchar: {
109 {
110 // use two u8 for each character of u16str 102 // use two u8 for each character of u16str
111 std::vector<u8> to_return(u16str.size() * 2); 103 std::vector<u8> to_return(u16str.size() * 2);
112 for (size_t i = 0; i < u16str.size(); ++i) { 104 for (size_t i = 0; i < u16str.size(); ++i) {
113 u16 tmp_char = u16str.at(i); 105 u16 tmp_char = u16str.at(i);
114 to_return[i*2] = (tmp_char & 0xFF00) >> 8; 106 to_return[i * 2] = (tmp_char & 0xFF00) >> 8;
115 to_return[i*2 + 1] = (tmp_char & 0x00FF); 107 to_return[i * 2 + 1] = (tmp_char & 0x00FF);
116 } 108 }
117 return to_return; 109 return to_return;
118 } 110 }
119 case Empty: 111 case Empty:
120 return{}; 112 return {};
121 case Invalid: 113 case Invalid:
122 default: 114 default:
123 // TODO(yuriks): Add assert 115 // TODO(yuriks): Add assert
124 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); 116 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
125 return{}; 117 return {};
126 } 118 }
127} 119}
128
129} 120}
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h
index 5d91e47f3..d69c3c785 100644
--- a/src/core/file_sys/archive_backend.h
+++ b/src/core/file_sys/archive_backend.h
@@ -8,14 +8,11 @@
8#include <string> 8#include <string>
9#include <utility> 9#include <utility>
10#include <vector> 10#include <vector>
11
12#include "common/bit_field.h" 11#include "common/bit_field.h"
13#include "common/common_types.h" 12#include "common/common_types.h"
14#include "common/swap.h" 13#include "common/swap.h"
15
16#include "core/hle/result.h" 14#include "core/hle/result.h"
17 15
18
19namespace FileSys { 16namespace FileSys {
20 17
21class FileBackend; 18class FileBackend;
@@ -24,10 +21,10 @@ class DirectoryBackend;
24// Path string type 21// Path string type
25enum LowPathType : u32 { 22enum LowPathType : u32 {
26 Invalid = 0, 23 Invalid = 0,
27 Empty = 1, 24 Empty = 1,
28 Binary = 2, 25 Binary = 2,
29 Char = 3, 26 Char = 3,
30 Wchar = 4 27 Wchar = 4,
31}; 28};
32 29
33union Mode { 30union Mode {
@@ -44,7 +41,9 @@ public:
44 Path(std::vector<u8> binary_data) : type(Binary), binary(std::move(binary_data)) {} 41 Path(std::vector<u8> binary_data) : type(Binary), binary(std::move(binary_data)) {}
45 Path(LowPathType type, u32 size, u32 pointer); 42 Path(LowPathType type, u32 size, u32 pointer);
46 43
47 LowPathType GetType() const { return type; } 44 LowPathType GetType() const {
45 return type;
46 }
48 47
49 /** 48 /**
50 * Gets the string representation of the path for debugging 49 * Gets the string representation of the path for debugging
@@ -63,18 +62,18 @@ private:
63 std::u16string u16str; 62 std::u16string u16str;
64}; 63};
65 64
65/// Parameters of the archive, as specified in the Create or Format call.
66struct ArchiveFormatInfo { 66struct ArchiveFormatInfo {
67 u32_le total_size; ///< The pre-defined size of the archive, as specified in the Create or Format call 67 u32_le total_size; ///< The pre-defined size of the archive.
68 u32_le number_directories; ///< The pre-defined number of directories in the archive, as specified in the Create or Format call 68 u32_le number_directories; ///< The pre-defined number of directories in the archive.
69 u32_le number_files; ///< The pre-defined number of files in the archive, as specified in the Create or Format call 69 u32_le number_files; ///< The pre-defined number of files in the archive.
70 u8 duplicate_data; ///< Whether the archive should duplicate the data, as specified in the Create or Format call 70 u8 duplicate_data; ///< Whether the archive should duplicate the data.
71}; 71};
72static_assert(std::is_pod<ArchiveFormatInfo>::value, "ArchiveFormatInfo is not POD"); 72static_assert(std::is_pod<ArchiveFormatInfo>::value, "ArchiveFormatInfo is not POD");
73 73
74class ArchiveBackend : NonCopyable { 74class ArchiveBackend : NonCopyable {
75public: 75public:
76 virtual ~ArchiveBackend() { 76 virtual ~ArchiveBackend() {}
77 }
78 77
79 /** 78 /**
80 * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) 79 * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
@@ -87,7 +86,8 @@ public:
87 * @param mode Mode to open the file with 86 * @param mode Mode to open the file with
88 * @return Opened file, or error code 87 * @return Opened file, or error code
89 */ 88 */
90 virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const = 0; 89 virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
90 const Mode mode) const = 0;
91 91
92 /** 92 /**
93 * Delete a file specified by its path 93 * Delete a file specified by its path
@@ -150,8 +150,7 @@ public:
150 150
151class ArchiveFactory : NonCopyable { 151class ArchiveFactory : NonCopyable {
152public: 152public:
153 virtual ~ArchiveFactory() { 153 virtual ~ArchiveFactory() {}
154 }
155 154
156 /** 155 /**
157 * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) 156 * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp
index 1d9eaefcb..e1d29efd3 100644
--- a/src/core/file_sys/archive_extsavedata.cpp
+++ b/src/core/file_sys/archive_extsavedata.cpp
@@ -5,12 +5,10 @@
5#include <algorithm> 5#include <algorithm>
6#include <memory> 6#include <memory>
7#include <vector> 7#include <vector>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10#include "common/file_util.h" 9#include "common/file_util.h"
11#include "common/logging/log.h" 10#include "common/logging/log.h"
12#include "common/string_util.h" 11#include "common/string_util.h"
13
14#include "core/file_sys/archive_extsavedata.h" 12#include "core/file_sys/archive_extsavedata.h"
15#include "core/file_sys/disk_archive.h" 13#include "core/file_sys/disk_archive.h"
16#include "core/hle/service/fs/archive.h" 14#include "core/hle/service/fs/archive.h"
@@ -30,10 +28,11 @@ std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path)
30 28
31std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) { 29std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) {
32 if (shared) 30 if (shared)
33 return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID.c_str()); 31 return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(),
32 SYSTEM_ID.c_str());
34 33
35 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(), 34 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(),
36 SYSTEM_ID.c_str(), SDCARD_ID.c_str()); 35 SYSTEM_ID.c_str(), SDCARD_ID.c_str());
37} 36}
38 37
39Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) { 38Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) {
@@ -54,11 +53,12 @@ Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) {
54 for (unsigned i = 0; i < 4; ++i) 53 for (unsigned i = 0; i < 4; ++i)
55 binary_path.push_back((high >> (8 * i)) & 0xFF); 54 binary_path.push_back((high >> (8 * i)) & 0xFF);
56 55
57 return { binary_path }; 56 return {binary_path};
58} 57}
59 58
60ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location, bool shared) 59ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location,
61 : shared(shared), mount_point(GetExtDataContainerPath(mount_location, shared)) { 60 bool shared)
61 : shared(shared), mount_point(GetExtDataContainerPath(mount_location, shared)) {
62 LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str()); 62 LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str());
63} 63}
64 64
@@ -88,7 +88,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
88 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); 88 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
89} 89}
90 90
91ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { 91ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path,
92 const FileSys::ArchiveFormatInfo& format_info) {
92 // These folders are always created with the ExtSaveData 93 // These folders are always created with the ExtSaveData
93 std::string user_path = GetExtSaveDataPath(mount_point, path) + "user/"; 94 std::string user_path = GetExtSaveDataPath(mount_point, path) + "user/";
94 std::string boss_path = GetExtSaveDataPath(mount_point, path) + "boss/"; 95 std::string boss_path = GetExtSaveDataPath(mount_point, path) + "boss/";
@@ -115,7 +116,8 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Pat
115 if (!file.IsOpen()) { 116 if (!file.IsOpen()) {
116 LOG_ERROR(Service_FS, "Could not open metadata information for archive"); 117 LOG_ERROR(Service_FS, "Could not open metadata information for archive");
117 // TODO(Subv): Verify error code 118 // TODO(Subv): Verify error code
118 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); 119 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
120 ErrorSummary::InvalidState, ErrorLevel::Status);
119 } 121 }
120 122
121 ArchiveFormatInfo info = {}; 123 ArchiveFormatInfo info = {};
@@ -123,7 +125,8 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Pat
123 return MakeResult<ArchiveFormatInfo>(info); 125 return MakeResult<ArchiveFormatInfo>(info);
124} 126}
125 127
126void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data, size_t icon_size) { 128void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data,
129 size_t icon_size) {
127 std::string game_path = FileSys::GetExtSaveDataPath(GetMountPoint(), path); 130 std::string game_path = FileSys::GetExtSaveDataPath(GetMountPoint(), path);
128 FileUtil::IOFile icon_file(game_path + "icon", "wb"); 131 FileUtil::IOFile icon_file(game_path + "icon", "wb");
129 icon_file.WriteBytes(icon_data, icon_size); 132 icon_file.WriteBytes(icon_data, icon_size);
diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h
index e9a72850d..6a3431e94 100644
--- a/src/core/file_sys/archive_extsavedata.h
+++ b/src/core/file_sys/archive_extsavedata.h
@@ -6,9 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/file_sys/archive_backend.h" 10#include "core/file_sys/archive_backend.h"
13#include "core/hle/result.h" 11#include "core/hle/result.h"
14 12
@@ -28,13 +26,17 @@ public:
28 */ 26 */
29 bool Initialize(); 27 bool Initialize();
30 28
31 std::string GetName() const override { return "ExtSaveData"; } 29 std::string GetName() const override {
30 return "ExtSaveData";
31 }
32 32
33 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; 33 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override;
34 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; 34 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
35 ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; 35 ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
36 36
37 const std::string& GetMountPoint() const { return mount_point; } 37 const std::string& GetMountPoint() const {
38 return mount_point;
39 }
38 40
39 /** 41 /**
40 * Writes the SMDH icon of the ExtSaveData to file 42 * Writes the SMDH icon of the ExtSaveData to file
@@ -45,7 +47,8 @@ public:
45 void WriteIcon(const Path& path, const u8* icon_data, size_t icon_size); 47 void WriteIcon(const Path& path, const u8* icon_data, size_t icon_size);
46 48
47private: 49private:
48 bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData archive 50 bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData
51 /// archive
49 52
50 /** 53 /**
51 * This holds the full directory path for this archive, it is only set after a successful call 54 * This holds the full directory path for this archive, it is only set after a successful call
@@ -65,7 +68,8 @@ private:
65std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path); 68std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path);
66 69
67/** 70/**
68 * Constructs a path to the base folder to hold concrete ExtSaveData archives in the host file system. 71 * Constructs a path to the base folder to hold concrete ExtSaveData archives in the host file
72 * system.
69 * @param mount_point The base folder where this folder resides, ie. SDMC or NAND. 73 * @param mount_point The base folder where this folder resides, ie. SDMC or NAND.
70 * @param shared Whether this ExtSaveData container is for SharedExtSaveDatas or not. 74 * @param shared Whether this ExtSaveData container is for SharedExtSaveDatas or not.
71 * @returns The path to the base ExtSaveData archives' folder in the host file system 75 * @returns The path to the base ExtSaveData archives' folder in the host file system
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
index 38828b546..6c99ca5b4 100644
--- a/src/core/file_sys/archive_romfs.cpp
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -4,10 +4,8 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <memory> 6#include <memory>
7
8#include "common/common_types.h" 7#include "common/common_types.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10
11#include "core/file_sys/archive_romfs.h" 9#include "core/file_sys/archive_romfs.h"
12#include "core/file_sys/ivfc_archive.h" 10#include "core/file_sys/ivfc_archive.h"
13 11
@@ -28,11 +26,12 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_RomFS::Open(const Path
28 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); 26 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
29} 27}
30 28
31ResultCode ArchiveFactory_RomFS::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { 29ResultCode ArchiveFactory_RomFS::Format(const Path& path,
30 const FileSys::ArchiveFormatInfo& format_info) {
32 LOG_ERROR(Service_FS, "Attempted to format a RomFS archive."); 31 LOG_ERROR(Service_FS, "Attempted to format a RomFS archive.");
33 // TODO: Verify error code 32 // TODO: Verify error code
34 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, 33 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported,
35 ErrorSummary::NotSupported, ErrorLevel::Permanent); 34 ErrorLevel::Permanent);
36} 35}
37 36
38ResultVal<ArchiveFormatInfo> ArchiveFactory_RomFS::GetFormatInfo(const Path& path) const { 37ResultVal<ArchiveFormatInfo> ArchiveFactory_RomFS::GetFormatInfo(const Path& path) const {
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
index c5a329122..8a8082a05 100644
--- a/src/core/file_sys/archive_romfs.h
+++ b/src/core/file_sys/archive_romfs.h
@@ -7,9 +7,7 @@
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9#include <vector> 9#include <vector>
10
11#include "common/common_types.h" 10#include "common/common_types.h"
12
13#include "core/file_sys/archive_backend.h" 11#include "core/file_sys/archive_backend.h"
14#include "core/hle/result.h" 12#include "core/hle/result.h"
15#include "core/loader/loader.h" 13#include "core/loader/loader.h"
@@ -24,7 +22,9 @@ class ArchiveFactory_RomFS final : public ArchiveFactory {
24public: 22public:
25 ArchiveFactory_RomFS(Loader::AppLoader& app_loader); 23 ArchiveFactory_RomFS(Loader::AppLoader& app_loader);
26 24
27 std::string GetName() const override { return "RomFS"; } 25 std::string GetName() const override {
26 return "RomFS";
27 }
28 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; 28 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override;
29 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; 29 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
30 ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; 30 ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp
index fd5711e14..6711035ec 100644
--- a/src/core/file_sys/archive_savedata.cpp
+++ b/src/core/file_sys/archive_savedata.cpp
@@ -4,12 +4,10 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <memory> 6#include <memory>
7
8#include "common/common_types.h" 7#include "common/common_types.h"
9#include "common/file_util.h" 8#include "common/file_util.h"
10#include "common/logging/log.h" 9#include "common/logging/log.h"
11#include "common/string_util.h" 10#include "common/string_util.h"
12
13#include "core/file_sys/archive_savedata.h" 11#include "core/file_sys/archive_savedata.h"
14#include "core/file_sys/disk_archive.h" 12#include "core/file_sys/disk_archive.h"
15#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
@@ -22,48 +20,54 @@ namespace FileSys {
22 20
23static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { 21static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) {
24 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(), 22 return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(),
25 SYSTEM_ID.c_str(), SDCARD_ID.c_str()); 23 SYSTEM_ID.c_str(), SDCARD_ID.c_str());
26} 24}
27 25
28static std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) { 26static std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) {
29 u32 high = (u32)(program_id >> 32); 27 u32 high = (u32)(program_id >> 32);
30 u32 low = (u32)(program_id & 0xFFFFFFFF); 28 u32 low = (u32)(program_id & 0xFFFFFFFF);
31 return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); 29 return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high,
30 low);
32} 31}
33 32
34static std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 program_id) { 33static std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 program_id) {
35 u32 high = (u32)(program_id >> 32); 34 u32 high = (u32)(program_id >> 32);
36 u32 low = (u32)(program_id & 0xFFFFFFFF); 35 u32 low = (u32)(program_id & 0xFFFFFFFF);
37 return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(), high, low); 36 return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(),
37 high, low);
38} 38}
39 39
40ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory) 40ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory)
41 : mount_point(GetSaveDataContainerPath(sdmc_directory)) { 41 : mount_point(GetSaveDataContainerPath(sdmc_directory)) {
42 LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); 42 LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str());
43} 43}
44 44
45ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { 45ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) {
46 std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); 46 std::string concrete_mount_point =
47 GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id);
47 if (!FileUtil::Exists(concrete_mount_point)) { 48 if (!FileUtil::Exists(concrete_mount_point)) {
48 // When a SaveData archive is created for the first time, it is not yet formatted 49 // When a SaveData archive is created for the first time, it is not yet formatted and the
49 // and the save file/directory structure expected by the game has not yet been initialized. 50 // save file/directory structure expected by the game has not yet been initialized.
50 // Returning the NotFormatted error code will signal the game to provision the SaveData archive 51 // Returning the NotFormatted error code will signal the game to provision the SaveData
51 // with the files and folders that it expects. 52 // archive with the files and folders that it expects.
52 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, 53 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
53 ErrorSummary::InvalidState, ErrorLevel::Status); 54 ErrorSummary::InvalidState, ErrorLevel::Status);
54 } 55 }
55 56
56 auto archive = std::make_unique<DiskArchive>(std::move(concrete_mount_point)); 57 auto archive = std::make_unique<DiskArchive>(std::move(concrete_mount_point));
57 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); 58 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
58} 59}
59 60
60ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { 61ResultCode ArchiveFactory_SaveData::Format(const Path& path,
61 std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); 62 const FileSys::ArchiveFormatInfo& format_info) {
63 std::string concrete_mount_point =
64 GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id);
62 FileUtil::DeleteDirRecursively(concrete_mount_point); 65 FileUtil::DeleteDirRecursively(concrete_mount_point);
63 FileUtil::CreateFullPath(concrete_mount_point); 66 FileUtil::CreateFullPath(concrete_mount_point);
64 67
65 // Write the format metadata 68 // Write the format metadata
66 std::string metadata_path = GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); 69 std::string metadata_path =
70 GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id);
67 FileUtil::IOFile file(metadata_path, "wb"); 71 FileUtil::IOFile file(metadata_path, "wb");
68 72
69 if (file.IsOpen()) { 73 if (file.IsOpen()) {
@@ -74,13 +78,15 @@ ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::Arch
74} 78}
75 79
76ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { 80ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const {
77 std::string metadata_path = GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); 81 std::string metadata_path =
82 GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id);
78 FileUtil::IOFile file(metadata_path, "rb"); 83 FileUtil::IOFile file(metadata_path, "rb");
79 84
80 if (!file.IsOpen()) { 85 if (!file.IsOpen()) {
81 LOG_ERROR(Service_FS, "Could not open metadata information for archive"); 86 LOG_ERROR(Service_FS, "Could not open metadata information for archive");
82 // TODO(Subv): Verify error code 87 // TODO(Subv): Verify error code
83 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); 88 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
89 ErrorSummary::InvalidState, ErrorLevel::Status);
84 } 90 }
85 91
86 ArchiveFormatInfo info = {}; 92 ArchiveFormatInfo info = {};
diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h
index 7a5a24089..6a372865a 100644
--- a/src/core/file_sys/archive_savedata.h
+++ b/src/core/file_sys/archive_savedata.h
@@ -6,7 +6,6 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9
10#include "core/file_sys/archive_backend.h" 9#include "core/file_sys/archive_backend.h"
11#include "core/hle/result.h" 10#include "core/hle/result.h"
12 11
@@ -20,7 +19,9 @@ class ArchiveFactory_SaveData final : public ArchiveFactory {
20public: 19public:
21 ArchiveFactory_SaveData(const std::string& mount_point); 20 ArchiveFactory_SaveData(const std::string& mount_point);
22 21
23 std::string GetName() const override { return "SaveData"; } 22 std::string GetName() const override {
23 return "SaveData";
24 }
24 25
25 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; 26 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override;
26 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; 27 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp
index 9f65e5455..6c4542b7d 100644
--- a/src/core/file_sys/archive_savedatacheck.cpp
+++ b/src/core/file_sys/archive_savedatacheck.cpp
@@ -5,12 +5,10 @@
5#include <algorithm> 5#include <algorithm>
6#include <memory> 6#include <memory>
7#include <vector> 7#include <vector>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10#include "common/file_util.h" 9#include "common/file_util.h"
11#include "common/logging/log.h" 10#include "common/logging/log.h"
12#include "common/string_util.h" 11#include "common/string_util.h"
13
14#include "core/file_sys/archive_savedatacheck.h" 12#include "core/file_sys/archive_savedatacheck.h"
15#include "core/file_sys/ivfc_archive.h" 13#include "core/file_sys/ivfc_archive.h"
16#include "core/hle/service/fs/archive.h" 14#include "core/hle/service/fs/archive.h"
@@ -25,13 +23,12 @@ static std::string GetSaveDataCheckContainerPath(const std::string& nand_directo
25} 23}
26 24
27static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high, u32 low) { 25static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high, u32 low) {
28 return Common::StringFromFormat("%s%08x/%08x/content/00000000.app.romfs", 26 return Common::StringFromFormat("%s%08x/%08x/content/00000000.app.romfs", mount_point.c_str(),
29 mount_point.c_str(), high, low); 27 high, low);
30} 28}
31 29
32ArchiveFactory_SaveDataCheck::ArchiveFactory_SaveDataCheck(const std::string& nand_directory) : 30ArchiveFactory_SaveDataCheck::ArchiveFactory_SaveDataCheck(const std::string& nand_directory)
33 mount_point(GetSaveDataCheckContainerPath(nand_directory)) { 31 : mount_point(GetSaveDataCheckContainerPath(nand_directory)) {}
34}
35 32
36ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(const Path& path) { 33ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(const Path& path) {
37 auto vec = path.AsBinary(); 34 auto vec = path.AsBinary();
@@ -48,11 +45,12 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(co
48 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); 45 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
49} 46}
50 47
51ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { 48ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path,
49 const FileSys::ArchiveFormatInfo& format_info) {
52 LOG_ERROR(Service_FS, "Attempted to format a SaveDataCheck archive."); 50 LOG_ERROR(Service_FS, "Attempted to format a SaveDataCheck archive.");
53 // TODO: Verify error code 51 // TODO: Verify error code
54 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, 52 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported,
55 ErrorSummary::NotSupported, ErrorLevel::Permanent); 53 ErrorLevel::Permanent);
56} 54}
57 55
58ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveDataCheck::GetFormatInfo(const Path& path) const { 56ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveDataCheck::GetFormatInfo(const Path& path) const {
diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h
index ea2624d64..e9cafbed9 100644
--- a/src/core/file_sys/archive_savedatacheck.h
+++ b/src/core/file_sys/archive_savedatacheck.h
@@ -6,7 +6,6 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9
10#include "core/file_sys/archive_backend.h" 9#include "core/file_sys/archive_backend.h"
11#include "core/hle/result.h" 10#include "core/hle/result.h"
12 11
@@ -20,7 +19,9 @@ class ArchiveFactory_SaveDataCheck final : public ArchiveFactory {
20public: 19public:
21 ArchiveFactory_SaveDataCheck(const std::string& mount_point); 20 ArchiveFactory_SaveDataCheck(const std::string& mount_point);
22 21
23 std::string GetName() const override { return "SaveDataCheck"; } 22 std::string GetName() const override {
23 return "SaveDataCheck";
24 }
24 25
25 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; 26 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override;
26 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; 27 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp
index 9b218af58..bcb03ed36 100644
--- a/src/core/file_sys/archive_sdmc.cpp
+++ b/src/core/file_sys/archive_sdmc.cpp
@@ -4,10 +4,8 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <memory> 6#include <memory>
7
8#include "common/file_util.h" 7#include "common/file_util.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10
11#include "core/file_sys/archive_sdmc.h" 9#include "core/file_sys/archive_sdmc.h"
12#include "core/file_sys/disk_archive.h" 10#include "core/file_sys/disk_archive.h"
13#include "core/settings.h" 11#include "core/settings.h"
@@ -17,7 +15,8 @@
17 15
18namespace FileSys { 16namespace FileSys {
19 17
20ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory) : sdmc_directory(sdmc_directory) { 18ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory)
19 : sdmc_directory(sdmc_directory) {
21 LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str()); 20 LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str());
22} 21}
23 22
@@ -40,7 +39,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path&
40 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); 39 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
41} 40}
42 41
43ResultCode ArchiveFactory_SDMC::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { 42ResultCode ArchiveFactory_SDMC::Format(const Path& path,
43 const FileSys::ArchiveFormatInfo& format_info) {
44 // This is kind of an undesirable operation, so let's just ignore it. :) 44 // This is kind of an undesirable operation, so let's just ignore it. :)
45 return RESULT_SUCCESS; 45 return RESULT_SUCCESS;
46} 46}
diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h
index 35c0f3725..88e855351 100644
--- a/src/core/file_sys/archive_sdmc.h
+++ b/src/core/file_sys/archive_sdmc.h
@@ -6,7 +6,6 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9
10#include "core/file_sys/archive_backend.h" 9#include "core/file_sys/archive_backend.h"
11#include "core/hle/result.h" 10#include "core/hle/result.h"
12 11
@@ -26,7 +25,9 @@ public:
26 */ 25 */
27 bool Initialize(); 26 bool Initialize();
28 27
29 std::string GetName() const override { return "SDMC"; } 28 std::string GetName() const override {
29 return "SDMC";
30 }
30 31
31 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; 32 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override;
32 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; 33 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp
index 1bcc228a1..48ebc0ed4 100644
--- a/src/core/file_sys/archive_systemsavedata.cpp
+++ b/src/core/file_sys/archive_systemsavedata.cpp
@@ -5,11 +5,9 @@
5#include <algorithm> 5#include <algorithm>
6#include <memory> 6#include <memory>
7#include <vector> 7#include <vector>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10#include "common/file_util.h" 9#include "common/file_util.h"
11#include "common/string_util.h" 10#include "common/string_util.h"
12
13#include "core/file_sys/archive_systemsavedata.h" 11#include "core/file_sys/archive_systemsavedata.h"
14#include "core/file_sys/disk_archive.h" 12#include "core/file_sys/disk_archive.h"
15#include "core/hle/service/fs/archive.h" 13#include "core/hle/service/fs/archive.h"
@@ -45,25 +43,25 @@ Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low) {
45 for (unsigned i = 0; i < 4; ++i) 43 for (unsigned i = 0; i < 4; ++i)
46 binary_path.push_back((low >> (8 * i)) & 0xFF); 44 binary_path.push_back((low >> (8 * i)) & 0xFF);
47 45
48 return { binary_path }; 46 return {binary_path};
49} 47}
50 48
51ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path) 49ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path)
52 : base_path(GetSystemSaveDataContainerPath(nand_path)) { 50 : base_path(GetSystemSaveDataContainerPath(nand_path)) {}
53}
54 51
55ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path) { 52ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path) {
56 std::string fullpath = GetSystemSaveDataPath(base_path, path); 53 std::string fullpath = GetSystemSaveDataPath(base_path, path);
57 if (!FileUtil::Exists(fullpath)) { 54 if (!FileUtil::Exists(fullpath)) {
58 // TODO(Subv): Check error code, this one is probably wrong 55 // TODO(Subv): Check error code, this one is probably wrong
59 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, 56 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
60 ErrorSummary::InvalidState, ErrorLevel::Status); 57 ErrorSummary::InvalidState, ErrorLevel::Status);
61 } 58 }
62 auto archive = std::make_unique<DiskArchive>(fullpath); 59 auto archive = std::make_unique<DiskArchive>(fullpath);
63 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); 60 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
64} 61}
65 62
66ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { 63ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path,
64 const FileSys::ArchiveFormatInfo& format_info) {
67 std::string fullpath = GetSystemSaveDataPath(base_path, path); 65 std::string fullpath = GetSystemSaveDataPath(base_path, path);
68 FileUtil::DeleteDirRecursively(fullpath); 66 FileUtil::DeleteDirRecursively(fullpath);
69 FileUtil::CreateFullPath(fullpath); 67 FileUtil::CreateFullPath(fullpath);
diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h
index 2bc13d4ee..a24b89f2b 100644
--- a/src/core/file_sys/archive_systemsavedata.h
+++ b/src/core/file_sys/archive_systemsavedata.h
@@ -6,9 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/file_sys/archive_backend.h" 10#include "core/file_sys/archive_backend.h"
13#include "core/hle/result.h" 11#include "core/hle/result.h"
14 12
@@ -26,7 +24,9 @@ public:
26 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; 24 ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
27 ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; 25 ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
28 26
29 std::string GetName() const override { return "SystemSaveData"; } 27 std::string GetName() const override {
28 return "SystemSaveData";
29 }
30 30
31private: 31private:
32 std::string base_path; 32 std::string base_path;
@@ -42,7 +42,8 @@ private:
42std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path); 42std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path);
43 43
44/** 44/**
45 * Constructs a path to the base folder to hold concrete SystemSaveData archives in the host file system. 45 * Constructs a path to the base folder to hold concrete SystemSaveData archives in the host file
46 * system.
46 * @param mount_point The base folder where this folder resides, ie. SDMC or NAND. 47 * @param mount_point The base folder where this folder resides, ie. SDMC or NAND.
47 * @returns The path to the base SystemSaveData archives' folder in the host file system 48 * @returns The path to the base SystemSaveData archives' folder in the host file system
48 */ 49 */
diff --git a/src/core/file_sys/directory_backend.h b/src/core/file_sys/directory_backend.h
index a25dc0cfa..b55e382ef 100644
--- a/src/core/file_sys/directory_backend.h
+++ b/src/core/file_sys/directory_backend.h
@@ -6,7 +6,6 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11 10
12//////////////////////////////////////////////////////////////////////////////////////////////////// 11////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,15 +18,16 @@ const size_t FILENAME_LENGTH = 0x20C / 2;
19struct Entry { 18struct Entry {
20 char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated) 19 char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated)
21 std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated) 20 std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated)
22 char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD) 21 char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD)
23 std::array<char, 4> extension; // 8.3 file extension (set to spaces for directories, null-terminated) 22 std::array<char, 4>
24 char unknown2; // unknown (always 0x01) 23 extension; // 8.3 file extension (set to spaces for directories, null-terminated)
25 char unknown3; // unknown (0x00 or 0x08) 24 char unknown2; // unknown (always 0x01)
25 char unknown3; // unknown (0x00 or 0x08)
26 char is_directory; // directory flag 26 char is_directory; // directory flag
27 char is_hidden; // hidden flag 27 char is_hidden; // hidden flag
28 char is_archive; // archive flag 28 char is_archive; // archive flag
29 char is_read_only; // read-only flag 29 char is_read_only; // read-only flag
30 u64 file_size; // file size (for files only) 30 u64 file_size; // file size (for files only)
31}; 31};
32static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!"); 32static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!");
33static_assert(offsetof(Entry, short_name) == 0x20C, "Wrong offset for short_name in Entry."); 33static_assert(offsetof(Entry, short_name) == 0x20C, "Wrong offset for short_name in Entry.");
@@ -37,8 +37,8 @@ static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size i
37 37
38class DirectoryBackend : NonCopyable { 38class DirectoryBackend : NonCopyable {
39public: 39public:
40 DirectoryBackend() { } 40 DirectoryBackend() {}
41 virtual ~DirectoryBackend() { } 41 virtual ~DirectoryBackend() {}
42 42
43 /** 43 /**
44 * Open the directory 44 * Open the directory
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
index 489cc96fb..0f66998e1 100644
--- a/src/core/file_sys/disk_archive.cpp
+++ b/src/core/file_sys/disk_archive.cpp
@@ -5,11 +5,9 @@
5#include <algorithm> 5#include <algorithm>
6#include <cstdio> 6#include <cstdio>
7#include <memory> 7#include <memory>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10#include "common/file_util.h" 9#include "common/file_util.h"
11#include "common/logging/log.h" 10#include "common/logging/log.h"
12
13#include "core/file_sys/disk_archive.h" 11#include "core/file_sys/disk_archive.h"
14 12
15//////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,7 +15,8 @@
17 15
18namespace FileSys { 16namespace FileSys {
19 17
20ResultVal<std::unique_ptr<FileBackend>> DiskArchive::OpenFile(const Path& path, const Mode mode) const { 18ResultVal<std::unique_ptr<FileBackend>> DiskArchive::OpenFile(const Path& path,
19 const Mode mode) const {
21 LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); 20 LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
22 auto file = std::make_unique<DiskFile>(*this, path, mode); 21 auto file = std::make_unique<DiskFile>(*this, path, mode);
23 ResultCode result = file->Open(); 22 ResultCode result = file->Open();
@@ -30,15 +29,18 @@ ResultCode DiskArchive::DeleteFile(const Path& path) const {
30 std::string file_path = mount_point + path.AsString(); 29 std::string file_path = mount_point + path.AsString();
31 30
32 if (FileUtil::IsDirectory(file_path)) 31 if (FileUtil::IsDirectory(file_path))
33 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 32 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled,
33 ErrorLevel::Status);
34 34
35 if (!FileUtil::Exists(file_path)) 35 if (!FileUtil::Exists(file_path))
36 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); 36 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound,
37 ErrorLevel::Status);
37 38
38 if (FileUtil::Delete(file_path)) 39 if (FileUtil::Delete(file_path))
39 return RESULT_SUCCESS; 40 return RESULT_SUCCESS;
40 41
41 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 42 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled,
43 ErrorLevel::Status);
42} 44}
43 45
44bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { 46bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
@@ -53,10 +55,12 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const {
53 std::string full_path = mount_point + path.AsString(); 55 std::string full_path = mount_point + path.AsString();
54 56
55 if (FileUtil::IsDirectory(full_path)) 57 if (FileUtil::IsDirectory(full_path))
56 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 58 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled,
59 ErrorLevel::Status);
57 60
58 if (FileUtil::Exists(full_path)) 61 if (FileUtil::Exists(full_path))
59 return ResultCode(ErrorDescription::FS_AlreadyExists, ErrorModule::FS, ErrorSummary::NothingHappened, ErrorLevel::Status); 62 return ResultCode(ErrorDescription::FS_AlreadyExists, ErrorModule::FS,
63 ErrorSummary::NothingHappened, ErrorLevel::Status);
60 64
61 if (size == 0) { 65 if (size == 0) {
62 FileUtil::CreateEmptyFile(full_path); 66 FileUtil::CreateEmptyFile(full_path);
@@ -69,10 +73,10 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const {
69 if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1) 73 if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1)
70 return RESULT_SUCCESS; 74 return RESULT_SUCCESS;
71 75
72 return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource, ErrorLevel::Info); 76 return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource,
77 ErrorLevel::Info);
73} 78}
74 79
75
76bool DiskArchive::CreateDirectory(const Path& path) const { 80bool DiskArchive::CreateDirectory(const Path& path) const {
77 return FileUtil::CreateDir(mount_point + path.AsString()); 81 return FileUtil::CreateDir(mount_point + path.AsString());
78} 82}
@@ -106,17 +110,21 @@ DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode
106 110
107ResultCode DiskFile::Open() { 111ResultCode DiskFile::Open() {
108 if (FileUtil::IsDirectory(path)) 112 if (FileUtil::IsDirectory(path))
109 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 113 return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled,
114 ErrorLevel::Status);
110 115
111 // Specifying only the Create flag is invalid 116 // Specifying only the Create flag is invalid
112 if (mode.create_flag && !mode.read_flag && !mode.write_flag) { 117 if (mode.create_flag && !mode.read_flag && !mode.write_flag) {
113 return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 118 return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS,
119 ErrorSummary::Canceled, ErrorLevel::Status);
114 } 120 }
115 121
116 if (!FileUtil::Exists(path)) { 122 if (!FileUtil::Exists(path)) {
117 if (!mode.create_flag) { 123 if (!mode.create_flag) {
118 LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str()); 124 LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.",
119 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); 125 path.c_str());
126 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS,
127 ErrorSummary::NotFound, ErrorLevel::Status);
120 } else { 128 } else {
121 // Create the file 129 // Create the file
122 FileUtil::CreateEmptyFile(path); 130 FileUtil::CreateEmptyFile(path);
@@ -135,20 +143,24 @@ ResultCode DiskFile::Open() {
135 file = std::make_unique<FileUtil::IOFile>(path, mode_string.c_str()); 143 file = std::make_unique<FileUtil::IOFile>(path, mode_string.c_str());
136 if (file->IsOpen()) 144 if (file->IsOpen())
137 return RESULT_SUCCESS; 145 return RESULT_SUCCESS;
138 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); 146 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound,
147 ErrorLevel::Status);
139} 148}
140 149
141ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const { 150ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
142 if (!mode.read_flag && !mode.write_flag) 151 if (!mode.read_flag && !mode.write_flag)
143 return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 152 return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS,
153 ErrorSummary::Canceled, ErrorLevel::Status);
144 154
145 file->Seek(offset, SEEK_SET); 155 file->Seek(offset, SEEK_SET);
146 return MakeResult<size_t>(file->ReadBytes(buffer, length)); 156 return MakeResult<size_t>(file->ReadBytes(buffer, length));
147} 157}
148 158
149ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { 159ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush,
160 const u8* buffer) const {
150 if (!mode.write_flag) 161 if (!mode.write_flag)
151 return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); 162 return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS,
163 ErrorSummary::Canceled, ErrorLevel::Status);
152 164
153 file->Seek(offset, SEEK_SET); 165 file->Seek(offset, SEEK_SET);
154 size_t written = file->WriteBytes(buffer, length); 166 size_t written = file->WriteBytes(buffer, length);
@@ -198,7 +210,8 @@ u32 DiskDirectory::Read(const u32 count, Entry* entries) {
198 const std::string& filename = file.virtualName; 210 const std::string& filename = file.virtualName;
199 Entry& entry = entries[entries_read]; 211 Entry& entry = entries[entries_read];
200 212
201 LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, file.isDirectory); 213 LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size,
214 file.isDirectory);
202 215
203 // TODO(Link Mauve): use a proper conversion to UTF-16. 216 // TODO(Link Mauve): use a proper conversion to UTF-16.
204 for (size_t j = 0; j < FILENAME_LENGTH; ++j) { 217 for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h
index b4cc2f702..2165f27f9 100644
--- a/src/core/file_sys/disk_archive.h
+++ b/src/core/file_sys/disk_archive.h
@@ -8,10 +8,8 @@
8#include <memory> 8#include <memory>
9#include <string> 9#include <string>
10#include <vector> 10#include <vector>
11
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "common/file_util.h" 12#include "common/file_util.h"
14
15#include "core/file_sys/archive_backend.h" 13#include "core/file_sys/archive_backend.h"
16#include "core/file_sys/directory_backend.h" 14#include "core/file_sys/directory_backend.h"
17#include "core/file_sys/file_backend.h" 15#include "core/file_sys/file_backend.h"
@@ -31,9 +29,12 @@ class DiskArchive : public ArchiveBackend {
31public: 29public:
32 DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {} 30 DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {}
33 31
34 virtual std::string GetName() const override { return "DiskArchive: " + mount_point; } 32 virtual std::string GetName() const override {
33 return "DiskArchive: " + mount_point;
34 }
35 35
36 ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const override; 36 ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
37 const Mode mode) const override;
37 ResultCode DeleteFile(const Path& path) const override; 38 ResultCode DeleteFile(const Path& path) const override;
38 bool RenameFile(const Path& src_path, const Path& dest_path) const override; 39 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
39 bool DeleteDirectory(const Path& path) const override; 40 bool DeleteDirectory(const Path& path) const override;
diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h
index 9137bbbad..ed997537f 100644
--- a/src/core/file_sys/file_backend.h
+++ b/src/core/file_sys/file_backend.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include <cstddef> 7#include <cstddef>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10#include "core/hle/result.h" 9#include "core/hle/result.h"
11 10
@@ -16,8 +15,8 @@ namespace FileSys {
16 15
17class FileBackend : NonCopyable { 16class FileBackend : NonCopyable {
18public: 17public:
19 FileBackend() { } 18 FileBackend() {}
20 virtual ~FileBackend() { } 19 virtual ~FileBackend() {}
21 20
22 /** 21 /**
23 * Open the file 22 * Open the file
@@ -42,7 +41,8 @@ public:
42 * @param buffer Buffer to read data from 41 * @param buffer Buffer to read data from
43 * @return Number of bytes written, or error code 42 * @return Number of bytes written, or error code
44 */ 43 */
45 virtual ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const = 0; 44 virtual ResultVal<size_t> Write(u64 offset, size_t length, bool flush,
45 const u8* buffer) const = 0;
46 46
47 /** 47 /**
48 * Get the size of the file in bytes 48 * Get the size of the file in bytes
diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp
index c61791ef7..49cc1de10 100644
--- a/src/core/file_sys/ivfc_archive.cpp
+++ b/src/core/file_sys/ivfc_archive.cpp
@@ -4,10 +4,8 @@
4 4
5#include <cstring> 5#include <cstring>
6#include <memory> 6#include <memory>
7
8#include "common/common_types.h" 7#include "common/common_types.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10
11#include "core/file_sys/ivfc_archive.h" 9#include "core/file_sys/ivfc_archive.h"
12 10
13//////////////////////////////////////////////////////////////////////////////////////////////////// 11////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,40 +17,49 @@ std::string IVFCArchive::GetName() const {
19 return "IVFC"; 17 return "IVFC";
20} 18}
21 19
22ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { 20ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path,
23 return MakeResult<std::unique_ptr<FileBackend>>(std::make_unique<IVFCFile>(romfs_file, data_offset, data_size)); 21 const Mode mode) const {
22 return MakeResult<std::unique_ptr<FileBackend>>(
23 std::make_unique<IVFCFile>(romfs_file, data_offset, data_size));
24} 24}
25 25
26ResultCode IVFCArchive::DeleteFile(const Path& path) const { 26ResultCode IVFCArchive::DeleteFile(const Path& path) const {
27 LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str()); 27 LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).",
28 GetName().c_str());
28 // TODO(Subv): Verify error code 29 // TODO(Subv): Verify error code
29 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, 30 return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled,
30 ErrorSummary::Canceled, ErrorLevel::Status); 31 ErrorLevel::Status);
31} 32}
32 33
33bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { 34bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
34 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); 35 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).",
36 GetName().c_str());
35 return false; 37 return false;
36} 38}
37 39
38bool IVFCArchive::DeleteDirectory(const Path& path) const { 40bool IVFCArchive::DeleteDirectory(const Path& path) const {
39 LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str()); 41 LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).",
42 GetName().c_str());
40 return false; 43 return false;
41} 44}
42 45
43ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const { 46ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const {
44 LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str()); 47 LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).",
48 GetName().c_str());
45 // TODO: Verify error code 49 // TODO: Verify error code
46 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); 50 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported,
51 ErrorLevel::Permanent);
47} 52}
48 53
49bool IVFCArchive::CreateDirectory(const Path& path) const { 54bool IVFCArchive::CreateDirectory(const Path& path) const {
50 LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str()); 55 LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).",
56 GetName().c_str());
51 return false; 57 return false;
52} 58}
53 59
54bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { 60bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
55 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); 61 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).",
62 GetName().c_str());
56 return false; 63 return false;
57} 64}
58 65
@@ -75,7 +82,8 @@ ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buff
75 return MakeResult<size_t>(romfs_file->ReadBytes(buffer, read_length)); 82 return MakeResult<size_t>(romfs_file->ReadBytes(buffer, read_length));
76} 83}
77 84
78ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { 85ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush,
86 const u8* buffer) const {
79 LOG_ERROR(Service_FS, "Attempted to write to IVFC file"); 87 LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
80 // TODO(Subv): Find error code 88 // TODO(Subv): Find error code
81 return MakeResult<size_t>(0); 89 return MakeResult<size_t>(0);
diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h
index 19d32dcca..0df6cf83a 100644
--- a/src/core/file_sys/ivfc_archive.h
+++ b/src/core/file_sys/ivfc_archive.h
@@ -8,10 +8,8 @@
8#include <memory> 8#include <memory>
9#include <string> 9#include <string>
10#include <vector> 10#include <vector>
11
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "common/file_util.h" 12#include "common/file_util.h"
14
15#include "core/file_sys/archive_backend.h" 13#include "core/file_sys/archive_backend.h"
16#include "core/file_sys/directory_backend.h" 14#include "core/file_sys/directory_backend.h"
17#include "core/file_sys/file_backend.h" 15#include "core/file_sys/file_backend.h"
@@ -34,7 +32,8 @@ public:
34 32
35 std::string GetName() const override; 33 std::string GetName() const override;
36 34
37 ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const override; 35 ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
36 const Mode mode) const override;
38 ResultCode DeleteFile(const Path& path) const override; 37 ResultCode DeleteFile(const Path& path) const override;
39 bool RenameFile(const Path& src_path, const Path& dest_path) const override; 38 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
40 bool DeleteDirectory(const Path& path) const override; 39 bool DeleteDirectory(const Path& path) const override;
@@ -55,13 +54,17 @@ public:
55 IVFCFile(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size) 54 IVFCFile(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
56 : romfs_file(file), data_offset(offset), data_size(size) {} 55 : romfs_file(file), data_offset(offset), data_size(size) {}
57 56
58 ResultCode Open() override { return RESULT_SUCCESS; } 57 ResultCode Open() override {
58 return RESULT_SUCCESS;
59 }
59 ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override; 60 ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
60 ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override; 61 ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
61 u64 GetSize() const override; 62 u64 GetSize() const override;
62 bool SetSize(u64 size) const override; 63 bool SetSize(u64 size) const override;
63 bool Close() const override { return false; } 64 bool Close() const override {
64 void Flush() const override { } 65 return false;
66 }
67 void Flush() const override {}
65 68
66private: 69private:
67 std::shared_ptr<FileUtil::IOFile> romfs_file; 70 std::shared_ptr<FileUtil::IOFile> romfs_file;
@@ -71,9 +74,15 @@ private:
71 74
72class IVFCDirectory : public DirectoryBackend { 75class IVFCDirectory : public DirectoryBackend {
73public: 76public:
74 bool Open() override { return false; } 77 bool Open() override {
75 u32 Read(const u32 count, Entry* entries) override { return 0; } 78 return false;
76 bool Close() const override { return false; } 79 }
80 u32 Read(const u32 count, Entry* entries) override {
81 return 0;
82 }
83 bool Close() const override {
84 return false;
85 }
77}; 86};
78 87
79} // namespace FileSys 88} // namespace FileSys