summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/common_paths.h1
-rw-r--r--src/common/file_util.cpp2
-rw-r--r--src/common/file_util.h1
-rw-r--r--src/core/CMakeLists.txt8
-rw-r--r--src/core/file_sys/archive_backend.h3
-rw-r--r--src/core/file_sys/archive_romfs.cpp47
-rw-r--r--src/core/file_sys/archive_romfs.h76
-rw-r--r--src/core/file_sys/archive_savedatacheck.cpp41
-rw-r--r--src/core/file_sys/archive_savedatacheck.h31
-rw-r--r--src/core/file_sys/directory_romfs.cpp32
-rw-r--r--src/core/file_sys/directory_romfs.h43
-rw-r--r--src/core/file_sys/file_romfs.cpp43
-rw-r--r--src/core/file_sys/file_romfs.h73
-rw-r--r--src/core/file_sys/ivfc_archive.cpp88
-rw-r--r--src/core/file_sys/ivfc_archive.h66
-rw-r--r--src/core/hle/service/fs/archive.cpp40
-rw-r--r--src/core/hle/service/fs/archive.h3
17 files changed, 279 insertions, 319 deletions
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index d3f0702bc..e692e5492 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -42,6 +42,7 @@
42#define SDMC_DIR "sdmc" 42#define SDMC_DIR "sdmc"
43#define EXTSAVEDATA_DIR "extsavedata" 43#define EXTSAVEDATA_DIR "extsavedata"
44#define SAVEDATA_DIR "savedata" 44#define SAVEDATA_DIR "savedata"
45#define SAVEDATACHECK_DIR "savedatacheck"
45#define SYSDATA_DIR "sysdata" 46#define SYSDATA_DIR "sysdata"
46#define SYSSAVEDATA_DIR "syssavedata" 47#define SYSSAVEDATA_DIR "syssavedata"
47#define SHADERCACHE_DIR "shader_cache" 48#define SHADERCACHE_DIR "shader_cache"
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index c44ad4ca1..0a6cd80c8 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -678,6 +678,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
678 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 678 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
679 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; 679 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
680 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; 680 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
681 paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP;
681 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; 682 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP;
682 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; 683 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
683 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 684 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
@@ -723,6 +724,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
723 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 724 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
724 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP; 725 paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
725 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP; 726 paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
727 paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP;
726 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP; 728 paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
727 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 729 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
728 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; 730 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
diff --git a/src/common/file_util.h b/src/common/file_util.h
index ec2415473..c83ecd87d 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -29,6 +29,7 @@ enum {
29 D_SDMC_IDX, 29 D_SDMC_IDX,
30 D_EXTSAVEDATA, 30 D_EXTSAVEDATA,
31 D_SAVEDATA_IDX, 31 D_SAVEDATA_IDX,
32 D_SAVEDATACHECK_IDX,
32 D_SYSDATA_IDX, 33 D_SYSDATA_IDX,
33 D_SYSSAVEDATA_IDX, 34 D_SYSSAVEDATA_IDX,
34 D_HIRESTEXTURES_IDX, 35 D_HIRESTEXTURES_IDX,
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 89ea70d23..addcb953c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -20,11 +20,11 @@ set(SRCS
20 file_sys/archive_extsavedata.cpp 20 file_sys/archive_extsavedata.cpp
21 file_sys/archive_romfs.cpp 21 file_sys/archive_romfs.cpp
22 file_sys/archive_savedata.cpp 22 file_sys/archive_savedata.cpp
23 file_sys/archive_savedatacheck.cpp
23 file_sys/archive_sdmc.cpp 24 file_sys/archive_sdmc.cpp
24 file_sys/archive_systemsavedata.cpp 25 file_sys/archive_systemsavedata.cpp
25 file_sys/disk_archive.cpp 26 file_sys/disk_archive.cpp
26 file_sys/file_romfs.cpp 27 file_sys/ivfc_archive.cpp
27 file_sys/directory_romfs.cpp
28 hle/kernel/address_arbiter.cpp 28 hle/kernel/address_arbiter.cpp
29 hle/kernel/event.cpp 29 hle/kernel/event.cpp
30 hle/kernel/kernel.cpp 30 hle/kernel/kernel.cpp
@@ -108,13 +108,13 @@ set(HEADERS
108 file_sys/archive_extsavedata.h 108 file_sys/archive_extsavedata.h
109 file_sys/archive_romfs.h 109 file_sys/archive_romfs.h
110 file_sys/archive_savedata.h 110 file_sys/archive_savedata.h
111 file_sys/archive_savedatacheck.h
111 file_sys/archive_sdmc.h 112 file_sys/archive_sdmc.h
112 file_sys/archive_systemsavedata.h 113 file_sys/archive_systemsavedata.h
113 file_sys/disk_archive.h 114 file_sys/disk_archive.h
114 file_sys/file_backend.h 115 file_sys/file_backend.h
115 file_sys/file_romfs.h 116 file_sys/ivfc_archive.h
116 file_sys/directory_backend.h 117 file_sys/directory_backend.h
117 file_sys/directory_romfs.h
118 hle/kernel/address_arbiter.h 118 hle/kernel/address_arbiter.h
119 hle/kernel/event.h 119 hle/kernel/event.h
120 hle/kernel/kernel.h 120 hle/kernel/kernel.h
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h
index 1612c35c2..390178f67 100644
--- a/src/core/file_sys/archive_backend.h
+++ b/src/core/file_sys/archive_backend.h
@@ -88,6 +88,7 @@ public:
88 const std::string DebugStr() const { 88 const std::string DebugStr() const {
89 switch (GetType()) { 89 switch (GetType()) {
90 case Invalid: 90 case Invalid:
91 default:
91 return "[Invalid]"; 92 return "[Invalid]";
92 case Empty: 93 case Empty:
93 return "[Empty]"; 94 return "[Empty]";
@@ -117,6 +118,7 @@ public:
117 return {}; 118 return {};
118 case Invalid: 119 case Invalid:
119 case Binary: 120 case Binary:
121 default:
120 // TODO(yuriks): Add assert 122 // TODO(yuriks): Add assert
121 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); 123 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
122 return {}; 124 return {};
@@ -159,6 +161,7 @@ public:
159 case Empty: 161 case Empty:
160 return {}; 162 return {};
161 case Invalid: 163 case Invalid:
164 default:
162 // TODO(yuriks): Add assert 165 // TODO(yuriks): Add assert
163 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); 166 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
164 return {}; 167 return {};
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
index 2fc3831b7..a30f73d0e 100644
--- a/src/core/file_sys/archive_romfs.cpp
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -5,11 +5,10 @@
5#include <memory> 5#include <memory>
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/file_util.h"
8#include "common/make_unique.h" 9#include "common/make_unique.h"
9 10
10#include "core/file_sys/archive_romfs.h" 11#include "core/file_sys/archive_romfs.h"
11#include "core/file_sys/directory_romfs.h"
12#include "core/file_sys/file_romfs.h"
13 12
14//////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace 14// FileSys namespace
@@ -23,48 +22,4 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) {
23 } 22 }
24} 23}
25 24
26std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
27 return Common::make_unique<File_RomFS>(this);
28}
29
30bool Archive_RomFS::DeleteFile(const Path& path) const {
31 LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS.");
32 return false;
33}
34
35bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const {
36 LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
37 return false;
38}
39
40bool Archive_RomFS::DeleteDirectory(const Path& path) const {
41 LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS.");
42 return false;
43}
44
45ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const {
46 LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS.");
47 // TODO: Verify error code
48 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
49}
50
51bool Archive_RomFS::CreateDirectory(const Path& path) const {
52 LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS.");
53 return false;
54}
55
56bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const {
57 LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
58 return false;
59}
60
61std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const {
62 return Common::make_unique<Directory_RomFS>();
63}
64
65ResultCode Archive_RomFS::Format(const Path& path) const {
66 LOG_WARNING(Service_FS, "Attempted to format ROMFS.");
67 return UnimplementedFunction(ErrorModule::FS);
68}
69
70} // namespace FileSys 25} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
index d4b1eb7f2..5cb75e04d 100644
--- a/src/core/file_sys/archive_romfs.h
+++ b/src/core/file_sys/archive_romfs.h
@@ -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_backend.h" 11#include "core/file_sys/ivfc_archive.h"
12#include "core/loader/loader.h" 12#include "core/loader/loader.h"
13 13
14//////////////////////////////////////////////////////////////////////////////////////////////////// 14////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,82 +17,12 @@
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 ArchiveBackend { 20class Archive_RomFS final : public IVFCArchive {
21public: 21public:
22 Archive_RomFS(const Loader::AppLoader& app_loader); 22 Archive_RomFS(const Loader::AppLoader& app_loader);
23 23
24 std::string GetName() const override { return "RomFS"; } 24 std::string GetName() const override { return "RomFS"; }
25 25 ResultCode Open(const Path& path) override { return RESULT_SUCCESS; }
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 */
32 std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
33
34 /**
35 * Delete a file specified by its path
36 * @param path Path relative to the archive
37 * @return Whether the file could be deleted
38 */
39 bool DeleteFile(const Path& path) const override;
40
41 /**
42 * Rename a File specified by its path
43 * @param src_path Source path relative to the archive
44 * @param dest_path Destination path relative to the archive
45 * @return Whether rename succeeded
46 */
47 bool RenameFile(const Path& src_path, const Path& dest_path) const override;
48
49 /**
50 * Delete a directory specified by its path
51 * @param path Path relative to the archive
52 * @return Whether the directory could be deleted
53 */
54 bool DeleteDirectory(const Path& path) const override;
55
56 /**
57 * Create a file specified by its path
58 * @param path Path relative to the Archive
59 * @param size The size of the new file, filled with zeroes
60 * @return File creation result code
61 */
62 ResultCode CreateFile(const Path& path, u32 size) const override;
63
64 /**
65 * Create a directory specified by its path
66 * @param path Path relative to the archive
67 * @return Whether the directory could be created
68 */
69 bool CreateDirectory(const Path& path) const override;
70
71 /**
72 * Rename a Directory specified by its path
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
76 */
77 bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
78
79 /**
80 * Open a directory specified by its path
81 * @param path Path relative to the archive
82 * @return Opened directory, or nullptr
83 */
84 std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
85
86 ResultCode Open(const Path& path) override {
87 return RESULT_SUCCESS;
88 }
89
90 ResultCode Format(const Path& path) const override;
91
92private:
93 friend class File_RomFS;
94
95 std::vector<u8> raw_data;
96}; 26};
97 27
98} // namespace FileSys 28} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp
new file mode 100644
index 000000000..233158a0c
--- /dev/null
+++ b/src/core/file_sys/archive_savedatacheck.cpp
@@ -0,0 +1,41 @@
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 "common/file_util.h"
6
7#include "core/file_sys/archive_savedatacheck.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// FileSys namespace
11
12namespace FileSys {
13
14Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) {
15}
16
17ResultCode Archive_SaveDataCheck::Open(const Path& path) {
18 // TODO(Subv): We should not be overwriting raw_data everytime this function is called,
19 // but until we use factory classes to create the archives at runtime instead of creating them beforehand
20 // and allow multiple archives of the same type to be open at the same time without clobbering each other,
21 // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed.
22 // There are a number of problems with this, for example opening a file in this archive, then opening
23 // this archive again with a different path, will corrupt the previously open file.
24 auto vec = path.AsBinary();
25 const u32* data = reinterpret_cast<u32*>(vec.data());
26 std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]);
27 FileUtil::IOFile file(file_path, "rb");
28
29 std::fill(raw_data.begin(), raw_data.end(), 0);
30
31 if (!file.IsOpen()) {
32 return ResultCode(-1); // TODO(Subv): Find the right error code
33 }
34 auto size = file.GetSize();
35 raw_data.resize(size);
36 file.ReadBytes(raw_data.data(), size);
37 file.Close();
38 return RESULT_SUCCESS;
39}
40
41} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h
new file mode 100644
index 000000000..f6e73e803
--- /dev/null
+++ b/src/core/file_sys/archive_savedatacheck.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 <vector>
8
9#include "common/common_types.h"
10
11#include "core/file_sys/ivfc_archive.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19/// File system interface to the SaveDataCheck archive
20class Archive_SaveDataCheck final : public IVFCArchive {
21public:
22 Archive_SaveDataCheck(const std::string& mount_point);
23
24 std::string GetName() const override { return "SaveDataCheck"; }
25 ResultCode Open(const Path& path) override;
26
27private:
28 std::string mount_point;
29};
30
31} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp
deleted file mode 100644
index e130aca17..000000000
--- a/src/core/file_sys/directory_romfs.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
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 "common/common_types.h"
6
7#include "core/file_sys/directory_romfs.h"
8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// FileSys namespace
11
12namespace FileSys {
13
14Directory_RomFS::Directory_RomFS() {
15}
16
17Directory_RomFS::~Directory_RomFS() {
18}
19
20bool Directory_RomFS::Open() {
21 return false;
22}
23
24u32 Directory_RomFS::Read(const u32 count, Entry* entries) {
25 return 0;
26}
27
28bool Directory_RomFS::Close() const {
29 return false;
30}
31
32} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h
deleted file mode 100644
index 2297f1645..000000000
--- a/src/core/file_sys/directory_romfs.h
+++ /dev/null
@@ -1,43 +0,0 @@
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/directory_backend.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17class Directory_RomFS final : public DirectoryBackend {
18public:
19 Directory_RomFS();
20 ~Directory_RomFS() override;
21
22 /**
23 * Open the directory
24 * @return true if the directory opened correctly
25 */
26 bool Open() override;
27
28 /**
29 * List files contained in the directory
30 * @param count Number of entries to return at once in entries
31 * @param entries Buffer to read data into
32 * @return Number of entries listed
33 */
34 u32 Read(const u32 count, Entry* entries) override;
35
36 /**
37 * Close the directory
38 * @return true if the directory closed correctly
39 */
40 bool Close() const override;
41};
42
43} // namespace FileSys
diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp
deleted file mode 100644
index 7467d6d31..000000000
--- a/src/core/file_sys/file_romfs.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
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 "common/common_types.h"
6
7#include "core/file_sys/file_romfs.h"
8#include "core/file_sys/archive_romfs.h"
9
10////////////////////////////////////////////////////////////////////////////////////////////////////
11// FileSys namespace
12
13namespace FileSys {
14
15bool File_RomFS::Open() {
16 return true;
17}
18
19size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
20 LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
21 memcpy(buffer, &archive->raw_data[(u32)offset], length);
22 return length;
23}
24
25size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
26 LOG_WARNING(Service_FS, "Attempted to write to ROMFS.");
27 return 0;
28}
29
30size_t File_RomFS::GetSize() const {
31 return sizeof(u8) * archive->raw_data.size();
32}
33
34bool File_RomFS::SetSize(const u64 size) const {
35 LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS");
36 return false;
37}
38
39bool File_RomFS::Close() const {
40 return false;
41}
42
43} // namespace FileSys
diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h
deleted file mode 100644
index 04d8a16a2..000000000
--- a/src/core/file_sys/file_romfs.h
+++ /dev/null
@@ -1,73 +0,0 @@
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/file_backend.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17class Archive_RomFS;
18
19class File_RomFS final : public FileBackend {
20public:
21 File_RomFS(const Archive_RomFS* archive) : archive(archive) {}
22
23 /**
24 * Open the file
25 * @return true if the file opened correctly
26 */
27 bool Open() override;
28
29 /**
30 * Read data from the file
31 * @param offset Offset in bytes to start reading data from
32 * @param length Length in bytes of data to read from file
33 * @param buffer Buffer to read data into
34 * @return Number of bytes read
35 */
36 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
37
38 /**
39 * Write data to the file
40 * @param offset Offset in bytes to start writing data to
41 * @param length Length in bytes of data to write to file
42 * @param flush The flush parameters (0 == do not flush)
43 * @param buffer Buffer to read data from
44 * @return Number of bytes written
45 */
46 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
47
48 /**
49 * Get the size of the file in bytes
50 * @return Size of the file in bytes
51 */
52 size_t GetSize() const override;
53
54 /**
55 * Set the size of the file in bytes
56 * @param size New size of the file
57 * @return true if successful
58 */
59 bool SetSize(const u64 size) const override;
60
61 /**
62 * Close the file
63 * @return true if the file closed correctly
64 */
65 bool Close() const override;
66
67 void Flush() const override { }
68
69private:
70 const Archive_RomFS* archive;
71};
72
73} // namespace FileSys
diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp
new file mode 100644
index 000000000..68c3c8b81
--- /dev/null
+++ b/src/core/file_sys/ivfc_archive.cpp
@@ -0,0 +1,88 @@
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 <memory>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9#include "common/make_unique.h"
10
11#include "core/file_sys/ivfc_archive.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18IVFCArchive::IVFCArchive() {
19}
20
21std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const {
22 return Common::make_unique<IVFCFile>(this);
23}
24
25bool IVFCArchive::DeleteFile(const Path& path) const {
26 LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str());
27 return false;
28}
29
30bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
31 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
32 return false;
33}
34
35bool IVFCArchive::DeleteDirectory(const Path& path) const {
36 LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str());
37 return false;
38}
39
40ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const {
41 LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str());
42 // TODO: Verify error code
43 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
44}
45
46bool IVFCArchive::CreateDirectory(const Path& path) const {
47 LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str());
48 return false;
49}
50
51bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
52 LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
53 return false;
54}
55
56std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) const {
57 return Common::make_unique<IVFCDirectory>();
58}
59
60ResultCode IVFCArchive::Format(const Path& path) const {
61 LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str());
62 // TODO: Verify error code
63 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
64}
65
66////////////////////////////////////////////////////////////////////////////////////////////////////
67
68size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const {
69 LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
70 memcpy(buffer, &archive->raw_data[(u32)offset], length);
71 return length;
72}
73
74size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
75 LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str());
76 return 0;
77}
78
79size_t IVFCFile::GetSize() const {
80 return sizeof(u8) * archive->raw_data.size();
81}
82
83bool IVFCFile::SetSize(const u64 size) const {
84 LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str());
85 return false;
86}
87
88} // namespace FileSys
diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h
new file mode 100644
index 000000000..6f4cc86df
--- /dev/null
+++ b/src/core/file_sys/ivfc_archive.h
@@ -0,0 +1,66 @@
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 <vector>
8
9#include "common/common_types.h"
10
11#include "core/file_sys/archive_backend.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19/**
20 * Helper which implements an interface to deal with IVFC images used in some archives
21 * This should be subclassed by concrete archive types, which will provide the
22 * input data (load the raw IVFC archive) and override any required methods
23 */
24class IVFCArchive : public ArchiveBackend {
25public:
26 IVFCArchive();
27
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 ResultCode Format(const Path& path) const override;
37
38protected:
39 friend class IVFCFile;
40 std::vector<u8> raw_data;
41};
42
43class IVFCFile : public FileBackend {
44public:
45 IVFCFile(const IVFCArchive* archive) : archive(archive) {}
46
47 bool Open() override { return true; }
48 size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
49 size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
50 size_t GetSize() const override;
51 bool SetSize(const u64 size) const override;
52 bool Close() const override { return false; }
53 void Flush() const override { }
54
55private:
56 const IVFCArchive* archive;
57};
58
59class IVFCDirectory : public DirectoryBackend {
60public:
61 bool Open() override { return false; }
62 u32 Read(const u32 count, Entry* entries) override { return 0; }
63 bool Close() const override { return false; }
64};
65
66} // namespace FileSys
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 9a91bcb8b..f761c6ab9 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -10,9 +10,11 @@
10#include "common/make_unique.h" 10#include "common/make_unique.h"
11#include "common/math_util.h" 11#include "common/math_util.h"
12 12
13#include "core/file_sys/archive_savedata.h"
14#include "core/file_sys/archive_extsavedata.h"
15#include "core/file_sys/archive_backend.h" 13#include "core/file_sys/archive_backend.h"
14#include "core/file_sys/archive_extsavedata.h"
15#include "core/file_sys/archive_romfs.h"
16#include "core/file_sys/archive_savedata.h"
17#include "core/file_sys/archive_savedatacheck.h"
16#include "core/file_sys/archive_sdmc.h" 18#include "core/file_sys/archive_sdmc.h"
17#include "core/file_sys/directory_backend.h" 19#include "core/file_sys/directory_backend.h"
18#include "core/hle/service/fs/archive.h" 20#include "core/hle/service/fs/archive.h"
@@ -50,6 +52,9 @@ enum class FileCommand : u32 {
50 SetAttributes = 0x08070040, 52 SetAttributes = 0x08070040,
51 Close = 0x08080000, 53 Close = 0x08080000,
52 Flush = 0x08090000, 54 Flush = 0x08090000,
55 SetPriority = 0x080A0040,
56 GetPriority = 0x080B0000,
57 OpenLinkFile = 0x080C0000,
53}; 58};
54 59
55// Command to access directory 60// Command to access directory
@@ -75,12 +80,13 @@ public:
75class File : public Kernel::Session { 80class File : public Kernel::Session {
76public: 81public:
77 File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) 82 File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
78 : path(path), backend(std::move(backend)) { 83 : path(path), backend(std::move(backend)), priority(0) {
79 } 84 }
80 85
81 std::string GetName() const override { return "Path: " + path.DebugStr(); } 86 std::string GetName() const override { return "Path: " + path.DebugStr(); }
82 87
83 FileSys::Path path; ///< Path of the file 88 FileSys::Path path; ///< Path of the file
89 u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
84 std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface 90 std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
85 91
86 ResultVal<bool> SyncRequest() override { 92 ResultVal<bool> SyncRequest() override {
@@ -145,6 +151,27 @@ public:
145 break; 151 break;
146 } 152 }
147 153
154 case FileCommand::OpenLinkFile:
155 {
156 LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
157 cmd_buff[3] = GetHandle();
158 break;
159 }
160
161 case FileCommand::SetPriority:
162 {
163 priority = cmd_buff[1];
164 LOG_TRACE(Service_FS, "SetPriority %u", priority);
165 break;
166 }
167
168 case FileCommand::GetPriority:
169 {
170 cmd_buff[2] = priority;
171 LOG_TRACE(Service_FS, "GetPriority");
172 break;
173 }
174
148 // Unknown command... 175 // Unknown command...
149 default: 176 default:
150 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); 177 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
@@ -327,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
327 ErrorSummary::Canceled, ErrorLevel::Status); 354 ErrorSummary::Canceled, ErrorLevel::Status);
328} 355}
329 356
330ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) { 357ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) {
331 Archive* archive = GetArchive(archive_handle); 358 Archive* archive = GetArchive(archive_handle);
332 if (archive == nullptr) 359 if (archive == nullptr)
333 return InvalidHandle(ErrorModule::FS); 360 return InvalidHandle(ErrorModule::FS);
@@ -435,6 +462,11 @@ void ArchiveInit() {
435 else 462 else
436 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", 463 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
437 sharedextsavedata_directory.c_str()); 464 sharedextsavedata_directory.c_str());
465
466 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
467 std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX);
468 auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory);
469 CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);
438} 470}
439 471
440/// Shutdown archives 472/// Shutdown archives
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index c23b8cc46..9e9efa019 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 {
22 SystemSaveData = 0x00000008, 22 SystemSaveData = 0x00000008,
23 SDMC = 0x00000009, 23 SDMC = 0x00000009,
24 SDMCWriteOnly = 0x0000000A, 24 SDMCWriteOnly = 0x0000000A,
25 SaveDataCheck = 0x2345678A,
25}; 26};
26 27
27typedef u64 ArchiveHandle; 28typedef u64 ArchiveHandle;
@@ -90,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
90 * @param file_size The size of the new file, filled with zeroes 91 * @param file_size The size of the new file, filled with zeroes
91 * @return File creation result code 92 * @return File creation result code
92 */ 93 */
93ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size); 94ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size);
94 95
95/** 96/**
96 * Create a Directory from an Archive 97 * Create a Directory from an Archive