summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Emmanuel Gil Peyrot2014-09-12 00:46:42 +0200
committerGravatar Emmanuel Gil Peyrot2014-09-17 14:35:46 +0000
commit33b0d1081e27b83408786e83ff7d13a4a2acb45c (patch)
tree5f0369be0738f053d46bc1782170e3d1b26616a6 /src
parentKernel: Add a File object and a getter for it from an Archive object. (diff)
downloadyuzu-33b0d1081e27b83408786e83ff7d13a4a2acb45c.tar.gz
yuzu-33b0d1081e27b83408786e83ff7d13a4a2acb45c.tar.xz
yuzu-33b0d1081e27b83408786e83ff7d13a4a2acb45c.zip
Core: Add a Directory object, with both a stub and a passthrough implementations.
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt5
-rw-r--r--src/core/file_sys/directory.h53
-rw-r--r--src/core/file_sys/directory_romfs.cpp38
-rw-r--r--src/core/file_sys/directory_romfs.h37
-rw-r--r--src/core/file_sys/directory_sdmc.cpp86
-rw-r--r--src/core/file_sys/directory_sdmc.h45
6 files changed, 264 insertions, 0 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 46e11d779..2b26292fd 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -26,6 +26,8 @@ set(SRCS
26 file_sys/archive_sdmc.cpp 26 file_sys/archive_sdmc.cpp
27 file_sys/file_romfs.cpp 27 file_sys/file_romfs.cpp
28 file_sys/file_sdmc.cpp 28 file_sys/file_sdmc.cpp
29 file_sys/directory_romfs.cpp
30 file_sys/directory_sdmc.cpp
29 hle/kernel/address_arbiter.cpp 31 hle/kernel/address_arbiter.cpp
30 hle/kernel/archive.cpp 32 hle/kernel/archive.cpp
31 hle/kernel/event.cpp 33 hle/kernel/event.cpp
@@ -84,6 +86,9 @@ set(HEADERS
84 file_sys/file.h 86 file_sys/file.h
85 file_sys/file_romfs.h 87 file_sys/file_romfs.h
86 file_sys/file_sdmc.h 88 file_sys/file_sdmc.h
89 file_sys/directory.h
90 file_sys/directory_romfs.h
91 file_sys/directory_sdmc.h
87 hle/kernel/address_arbiter.h 92 hle/kernel/address_arbiter.h
88 hle/kernel/archive.h 93 hle/kernel/archive.h
89 hle/kernel/event.h 94 hle/kernel/event.h
diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h
new file mode 100644
index 000000000..cf9a2010b
--- /dev/null
+++ b/src/core/file_sys/directory.h
@@ -0,0 +1,53 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/hle/kernel/kernel.h"
10
11////////////////////////////////////////////////////////////////////////////////////////////////////
12// FileSys namespace
13
14namespace FileSys {
15
16// Structure of a directory entry, from http://3dbrew.org/wiki/FSDir:Read#Entry_format
17const size_t FILENAME_LENGTH = 0x20C / 2;
18struct Entry {
19 char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated)
20 char short_name[8]; // 8.3 file name ('longfilename' -> 'LONGFI~1')
21 char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD)
22 char extension[3]; // 8.3 file extension (set to spaces for directories)
23 char unknown2; // unknown (always 0x01)
24 char unknown3; // unknown (0x00 or 0x08)
25 char is_directory; // directory flag
26 char is_hidden; // hidden flag
27 char is_archive; // archive flag
28 char is_read_only; // read-only flag
29 u64 file_size; // file size (for files only)
30};
31static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!");
32
33class Directory : NonCopyable {
34public:
35 Directory() { }
36 virtual ~Directory() { }
37
38 /**
39 * List files contained in the directory
40 * @param count Number of entries to return at once in entries
41 * @param entries Buffer to read data into
42 * @return Number of entries listed
43 */
44 virtual u32 Read(const u32 count, Entry* entries) = 0;
45
46 /**
47 * Close the directory
48 * @return true if the directory closed correctly
49 */
50 virtual bool Close() const = 0;
51};
52
53} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp
new file mode 100644
index 000000000..4e8f4c04d
--- /dev/null
+++ b/src/core/file_sys/directory_romfs.cpp
@@ -0,0 +1,38 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
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
20/**
21 * List files contained in the directory
22 * @param count Number of entries to return at once in entries
23 * @param entries Buffer to read data into
24 * @return Number of entries listed
25 */
26u32 Directory_RomFS::Read(const u32 count, Entry* entries) {
27 return 0;
28}
29
30/**
31 * Close the directory
32 * @return true if the directory closed correctly
33 */
34bool Directory_RomFS::Close() const {
35 return false;
36}
37
38} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h
new file mode 100644
index 000000000..4b71c4b13
--- /dev/null
+++ b/src/core/file_sys/directory_romfs.h
@@ -0,0 +1,37 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/file_sys/directory.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17class Directory_RomFS final : public Directory {
18public:
19 Directory_RomFS();
20 ~Directory_RomFS() override;
21
22 /**
23 * List files contained in the directory
24 * @param count Number of entries to return at once in entries
25 * @param entries Buffer to read data into
26 * @return Number of entries listed
27 */
28 u32 Read(const u32 count, Entry* entries) override;
29
30 /**
31 * Close the directory
32 * @return true if the directory closed correctly
33 */
34 bool Close() const override;
35};
36
37} // namespace FileSys
diff --git a/src/core/file_sys/directory_sdmc.cpp b/src/core/file_sys/directory_sdmc.cpp
new file mode 100644
index 000000000..11e867857
--- /dev/null
+++ b/src/core/file_sys/directory_sdmc.cpp
@@ -0,0 +1,86 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/directory_sdmc.h"
11#include "core/file_sys/archive_sdmc.h"
12
13////////////////////////////////////////////////////////////////////////////////////////////////////
14// FileSys namespace
15
16namespace FileSys {
17
18Directory_SDMC::Directory_SDMC(const Archive_SDMC* archive, const std::string& path) {
19 // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass
20 // the root directory we set while opening the archive.
21 // For example, opening /../../usr/bin can give the emulated program your installed programs.
22 std::string absolute_path = archive->GetMountPoint() + path;
23 entry_count = FileUtil::ScanDirectoryTree(absolute_path, entry);
24 current_entry = 0;
25}
26
27Directory_SDMC::~Directory_SDMC() {
28 Close();
29}
30
31/**
32 * List files contained in the directory
33 * @param count Number of entries to return at once in entries
34 * @param entries Buffer to read data into
35 * @return Number of entries listed
36 */
37u32 Directory_SDMC::Read(const u32 count, Entry* entries) {
38 u32 i;
39 for (i = 0; i < count && current_entry < entry_count; ++i) {
40 FileUtil::FSTEntry file = entry.children[current_entry];
41 std::string filename = file.virtualName;
42 WARN_LOG(FILESYS, "File %s: size=%d dir=%d", filename.c_str(), file.size, file.isDirectory);
43
44 Entry* entry = &entries[i];
45
46 // TODO(Link Mauve): use a proper conversion to UTF-16.
47 for (int j = 0; j < FILENAME_LENGTH; ++j) {
48 entry->filename[j] = filename[j];
49 if (!filename[j])
50 break;
51 }
52
53 // Split the filename into 8.3 format.
54 // TODO(Link Mauve): move that to common, I guess, and make it more robust to long filenames.
55 std::string::size_type n = filename.rfind('.');
56 if (n == std::string::npos) {
57 strncpy(entry->short_name, filename.c_str(), 8);
58 memset(entry->extension, '\0', 3);
59 } else {
60 strncpy(entry->short_name, filename.substr(0, n).c_str(), 8);
61 strncpy(entry->extension, filename.substr(n + 1).c_str(), 8);
62 }
63
64 entry->is_directory = file.isDirectory;
65 entry->file_size = file.size;
66
67 // We emulate a SD card where the archive bit has never been cleared, as it would be on
68 // most user SD cards.
69 // Some homebrews (blargSNES for instance) are known to mistakenly use the archive bit as a
70 // file bit.
71 entry->is_archive = !file.isDirectory;
72
73 ++current_entry;
74 }
75 return i;
76}
77
78/**
79 * Close the directory
80 * @return true if the directory closed correctly
81 */
82bool Directory_SDMC::Close() const {
83 return true;
84}
85
86} // namespace FileSys
diff --git a/src/core/file_sys/directory_sdmc.h b/src/core/file_sys/directory_sdmc.h
new file mode 100644
index 000000000..0bc6c9eff
--- /dev/null
+++ b/src/core/file_sys/directory_sdmc.h
@@ -0,0 +1,45 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/directory.h"
11#include "core/file_sys/archive_sdmc.h"
12#include "core/loader/loader.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19class Directory_SDMC final : public Directory {
20public:
21 Directory_SDMC();
22 Directory_SDMC(const Archive_SDMC* archive, const std::string& path);
23 ~Directory_SDMC() override;
24
25 /**
26 * List files contained in the directory
27 * @param count Number of entries to return at once in entries
28 * @param entries Buffer to read data into
29 * @return Number of entries listed
30 */
31 u32 Read(const u32 count, Entry* entries) override;
32
33 /**
34 * Close the directory
35 * @return true if the directory closed correctly
36 */
37 bool Close() const override;
38
39private:
40 u32 entry_count;
41 u32 current_entry;
42 FileUtil::FSTEntry entry;
43};
44
45} // namespace FileSys