summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt10
-rw-r--r--src/core/file_sys/directory.h37
-rw-r--r--src/core/file_sys/disk_filesystem.cpp109
-rw-r--r--src/core/file_sys/disk_filesystem.h27
-rw-r--r--src/core/file_sys/filesystem.h8
-rw-r--r--src/core/file_sys/romfs_filesystem.cpp5
-rw-r--r--src/core/file_sys/romfs_filesystem.h10
-rw-r--r--src/core/file_sys/sdmc_factory.cpp40
-rw-r--r--src/core/file_sys/sdmc_factory.h31
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp5
-rw-r--r--src/core/hle/service/filesystem/filesystem.h1
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp102
-rw-r--r--src/core/hle/service/service.cpp4
-rw-r--r--src/core/hle/service/spl/csrng.cpp18
-rw-r--r--src/core/hle/service/spl/csrng.h18
-rw-r--r--src/core/hle/service/spl/module.cpp42
-rw-r--r--src/core/hle/service/spl/module.h29
-rw-r--r--src/core/hle/service/spl/spl.cpp41
-rw-r--r--src/core/hle/service/spl/spl.h18
-rw-r--r--src/core/hle/service/ssl/ssl.cpp17
-rw-r--r--src/core/hle/service/ssl/ssl.h22
-rw-r--r--src/core/memory.cpp9
-rw-r--r--src/core/memory.h11
23 files changed, 546 insertions, 68 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 456b63ac2..39cdb55f1 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -22,6 +22,8 @@ add_library(core STATIC
file_sys/romfs_filesystem.h
file_sys/savedata_factory.cpp
file_sys/savedata_factory.h
+ file_sys/sdmc_factory.cpp
+ file_sys/sdmc_factory.h
file_sys/storage.h
frontend/emu_window.cpp
frontend/emu_window.h
@@ -193,6 +195,14 @@ add_library(core STATIC
hle/service/sockets/sfdnsres.h
hle/service/sockets/sockets.cpp
hle/service/sockets/sockets.h
+ hle/service/spl/csrng.cpp
+ hle/service/spl/csrng.h
+ hle/service/spl/module.cpp
+ hle/service/spl/module.h
+ hle/service/spl/spl.cpp
+ hle/service/spl/spl.h
+ hle/service/ssl/ssl.cpp
+ hle/service/ssl/ssl.h
hle/service/time/time.cpp
hle/service/time/time.h
hle/service/time/time_s.cpp
diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h
index 5a40bf472..c7639795e 100644
--- a/src/core/file_sys/directory.h
+++ b/src/core/file_sys/directory.h
@@ -6,34 +6,28 @@
#include <array>
#include <cstddef>
+#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "core/file_sys/filesystem.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
-// Structure of a directory entry, from http://3dbrew.org/wiki/FSDir:Read#Entry_format
-const size_t FILENAME_LENGTH = 0x20C / 2;
+// Structure of a directory entry, from
+// http://switchbrew.org/index.php?title=Filesystem_services#DirectoryEntry
+const size_t FILENAME_LENGTH = 0x300;
struct Entry {
- char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated)
- std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated)
- char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD)
- std::array<char, 4>
- extension; // 8.3 file extension (set to spaces for directories, null-terminated)
- char unknown2; // unknown (always 0x01)
- char unknown3; // unknown (0x00 or 0x08)
- char is_directory; // directory flag
- char is_hidden; // hidden flag
- char is_archive; // archive flag
- char is_read_only; // read-only flag
- u64 file_size; // file size (for files only)
+ char filename[FILENAME_LENGTH];
+ INSERT_PADDING_BYTES(4);
+ EntryType type;
+ INSERT_PADDING_BYTES(3);
+ u64 file_size;
};
-static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!");
-static_assert(offsetof(Entry, short_name) == 0x20C, "Wrong offset for short_name in Entry.");
-static_assert(offsetof(Entry, extension) == 0x216, "Wrong offset for extension in Entry.");
-static_assert(offsetof(Entry, is_archive) == 0x21E, "Wrong offset for is_archive in Entry.");
-static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size in Entry.");
+static_assert(sizeof(Entry) == 0x310, "Directory Entry struct isn't exactly 0x310 bytes long!");
+static_assert(offsetof(Entry, type) == 0x304, "Wrong offset for type in Entry.");
+static_assert(offsetof(Entry, file_size) == 0x308, "Wrong offset for file_size in Entry.");
class DirectoryBackend : NonCopyable {
public:
@@ -46,7 +40,10 @@ public:
* @param entries Buffer to read data into
* @return Number of entries listed
*/
- virtual u32 Read(const u32 count, Entry* entries) = 0;
+ virtual u64 Read(const u64 count, Entry* entries) = 0;
+
+ /// Returns the number of entries still left to read.
+ virtual u64 GetEntryCount() const = 0;
/**
* Close the directory
diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp
index 22b17ba04..3a4b45721 100644
--- a/src/core/file_sys/disk_filesystem.cpp
+++ b/src/core/file_sys/disk_filesystem.cpp
@@ -11,16 +11,43 @@
namespace FileSys {
+static std::string ModeFlagsToString(Mode mode) {
+ std::string mode_str;
+ u32 mode_flags = static_cast<u32>(mode);
+
+ // Calculate the correct open mode for the file.
+ if ((mode_flags & static_cast<u32>(Mode::Read)) &&
+ (mode_flags & static_cast<u32>(Mode::Write))) {
+ if (mode_flags & static_cast<u32>(Mode::Append))
+ mode_str = "a+";
+ else
+ mode_str = "r+";
+ } else {
+ if (mode_flags & static_cast<u32>(Mode::Read))
+ mode_str = "r";
+ else if (mode_flags & static_cast<u32>(Mode::Append))
+ mode_str = "a";
+ else if (mode_flags & static_cast<u32>(Mode::Write))
+ mode_str = "w";
+ }
+
+ mode_str += "b";
+
+ return mode_str;
+}
+
std::string Disk_FileSystem::GetName() const {
return "Disk";
}
ResultVal<std::unique_ptr<StorageBackend>> Disk_FileSystem::OpenFile(const std::string& path,
Mode mode) const {
- ASSERT_MSG(mode == Mode::Read || mode == Mode::Write, "Other file modes are not supported");
+
+ // Calculate the correct open mode for the file.
+ std::string mode_str = ModeFlagsToString(mode);
std::string full_path = base_directory + path;
- auto file = std::make_shared<FileUtil::IOFile>(full_path, mode == Mode::Read ? "rb" : "wb");
+ auto file = std::make_shared<FileUtil::IOFile>(full_path, mode_str.c_str());
if (!file->IsOpen()) {
return ERROR_PATH_NOT_FOUND;
@@ -75,8 +102,15 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const
return ResultCode(-1);
}
-ResultCode Disk_FileSystem::CreateDirectory(const Path& path) const {
- LOG_WARNING(Service_FS, "(STUBBED) called");
+ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const {
+ // TODO(Subv): Perform path validation to prevent escaping the emulator sandbox.
+ std::string full_path = base_directory + path;
+
+ if (FileUtil::CreateDir(full_path)) {
+ return RESULT_SUCCESS;
+ }
+
+ LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", full_path.c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
@@ -88,8 +122,17 @@ ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& de
}
ResultVal<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory(
- const Path& path) const {
- return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<Disk_Directory>());
+ const std::string& path) const {
+
+ std::string full_path = base_directory + path;
+
+ if (!FileUtil::IsDirectory(full_path)) {
+ // TODO(Subv): Find the correct error code for this.
+ return ResultCode(-1);
+ }
+
+ auto directory = std::make_unique<Disk_Directory>(full_path);
+ return MakeResult<std::unique_ptr<DirectoryBackend>>(std::move(directory));
}
u64 Disk_FileSystem::GetFreeSpaceSize() const {
@@ -103,8 +146,10 @@ ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& p
return ERROR_PATH_NOT_FOUND;
}
- // TODO(Subv): Find out the EntryType values
- UNIMPLEMENTED_MSG("Unimplemented GetEntryType");
+ if (FileUtil::IsDirectory(full_path))
+ return MakeResult(EntryType::Directory);
+
+ return MakeResult(EntryType::File);
}
ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
@@ -133,14 +178,50 @@ bool Disk_Storage::SetSize(const u64 size) const {
return false;
}
-u32 Disk_Directory::Read(const u32 count, Entry* entries) {
- LOG_WARNING(Service_FS, "(STUBBED) called");
- return 0;
+Disk_Directory::Disk_Directory(const std::string& path) : directory() {
+ unsigned size = FileUtil::ScanDirectoryTree(path, directory);
+ directory.size = size;
+ directory.isDirectory = true;
+ children_iterator = directory.children.begin();
}
-bool Disk_Directory::Close() const {
- LOG_WARNING(Service_FS, "(STUBBED) called");
- return true;
+u64 Disk_Directory::Read(const u64 count, Entry* entries) {
+ u64 entries_read = 0;
+
+ while (entries_read < count && children_iterator != directory.children.cend()) {
+ const FileUtil::FSTEntry& file = *children_iterator;
+ const std::string& filename = file.virtualName;
+ Entry& entry = entries[entries_read];
+
+ LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size,
+ file.isDirectory);
+
+ // TODO(Link Mauve): use a proper conversion to UTF-16.
+ for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
+ entry.filename[j] = filename[j];
+ if (!filename[j])
+ break;
+ }
+
+ if (file.isDirectory) {
+ entry.file_size = 0;
+ entry.type = EntryType::Directory;
+ } else {
+ entry.file_size = file.size;
+ entry.type = EntryType::File;
+ }
+
+ ++entries_read;
+ ++children_iterator;
+ }
+ return entries_read;
+}
+
+u64 Disk_Directory::GetEntryCount() const {
+ // We convert the children iterator into a const_iterator to allow template argument deduction
+ // in std::distance.
+ std::vector<FileUtil::FSTEntry>::const_iterator current = children_iterator;
+ return std::distance(current, directory.children.end());
}
} // namespace FileSys
diff --git a/src/core/file_sys/disk_filesystem.h b/src/core/file_sys/disk_filesystem.h
index 53767b949..742d7db1a 100644
--- a/src/core/file_sys/disk_filesystem.h
+++ b/src/core/file_sys/disk_filesystem.h
@@ -30,9 +30,10 @@ public:
ResultCode DeleteDirectory(const Path& path) const override;
ResultCode DeleteDirectoryRecursively(const Path& path) const override;
ResultCode CreateFile(const std::string& path, u64 size) const override;
- ResultCode CreateDirectory(const Path& path) const override;
+ ResultCode CreateDirectory(const std::string& path) const override;
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override;
- ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
+ ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(
+ const std::string& path) const override;
u64 GetFreeSpaceSize() const override;
ResultVal<EntryType> GetEntryType(const std::string& path) const override;
@@ -59,8 +60,26 @@ private:
class Disk_Directory : public DirectoryBackend {
public:
- u32 Read(const u32 count, Entry* entries) override;
- bool Close() const override;
+ Disk_Directory(const std::string& path);
+
+ ~Disk_Directory() override {
+ Close();
+ }
+
+ u64 Read(const u64 count, Entry* entries) override;
+ u64 GetEntryCount() const override;
+
+ bool Close() const override {
+ return true;
+ }
+
+protected:
+ u32 total_entries_in_directory;
+ FileUtil::FSTEntry directory;
+
+ // We need to remember the last entry we returned, so a subsequent call to Read will continue
+ // from the next one. This iterator will always point to the next unread entry.
+ std::vector<FileUtil::FSTEntry>::iterator children_iterator;
};
} // namespace FileSys
diff --git a/src/core/file_sys/filesystem.h b/src/core/file_sys/filesystem.h
index 94ad2abf2..399427ca2 100644
--- a/src/core/file_sys/filesystem.h
+++ b/src/core/file_sys/filesystem.h
@@ -27,7 +27,7 @@ enum LowPathType : u32 {
Wchar = 4,
};
-enum EntryType : u32 {
+enum EntryType : u8 {
Directory = 0,
File = 1,
};
@@ -35,6 +35,7 @@ enum EntryType : u32 {
enum class Mode : u32 {
Read = 1,
Write = 2,
+ Append = 4,
};
class Path {
@@ -103,7 +104,7 @@ public:
* @param path Path relative to the archive
* @return Result of the operation
*/
- virtual ResultCode CreateDirectory(const Path& path) const = 0;
+ virtual ResultCode CreateDirectory(const std::string& path) const = 0;
/**
* Delete a directory specified by its path
@@ -149,7 +150,8 @@ public:
* @param path Path relative to the archive
* @return Opened directory, or error code
*/
- virtual ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const = 0;
+ virtual ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(
+ const std::string& path) const = 0;
/**
* Get the free space
diff --git a/src/core/file_sys/romfs_filesystem.cpp b/src/core/file_sys/romfs_filesystem.cpp
index f1f9b4d04..0c6cc3157 100644
--- a/src/core/file_sys/romfs_filesystem.cpp
+++ b/src/core/file_sys/romfs_filesystem.cpp
@@ -55,7 +55,7 @@ ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const
return ResultCode(-1);
}
-ResultCode RomFS_FileSystem::CreateDirectory(const Path& path) const {
+ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const {
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive (%s).",
GetName().c_str());
// TODO(wwylele): Use correct error code
@@ -70,7 +70,8 @@ ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& d
}
ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory(
- const Path& path) const {
+ const std::string& path) const {
+ LOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive");
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>());
}
diff --git a/src/core/file_sys/romfs_filesystem.h b/src/core/file_sys/romfs_filesystem.h
index cedd70645..3f94c04d0 100644
--- a/src/core/file_sys/romfs_filesystem.h
+++ b/src/core/file_sys/romfs_filesystem.h
@@ -36,9 +36,10 @@ public:
ResultCode DeleteDirectory(const Path& path) const override;
ResultCode DeleteDirectoryRecursively(const Path& path) const override;
ResultCode CreateFile(const std::string& path, u64 size) const override;
- ResultCode CreateDirectory(const Path& path) const override;
+ ResultCode CreateDirectory(const std::string& path) const override;
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override;
- ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
+ ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(
+ const std::string& path) const override;
u64 GetFreeSpaceSize() const override;
ResultVal<EntryType> GetEntryType(const std::string& path) const override;
@@ -70,7 +71,10 @@ private:
class ROMFSDirectory : public DirectoryBackend {
public:
- u32 Read(const u32 count, Entry* entries) override {
+ u64 Read(const u64 count, Entry* entries) override {
+ return 0;
+ }
+ u64 GetEntryCount() const override {
return 0;
}
bool Close() const override {
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp
new file mode 100644
index 000000000..00e80d2a7
--- /dev/null
+++ b/src/core/file_sys/sdmc_factory.cpp
@@ -0,0 +1,40 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cinttypes>
+#include <memory>
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "common/string_util.h"
+#include "core/core.h"
+#include "core/file_sys/disk_filesystem.h"
+#include "core/file_sys/sdmc_factory.h"
+
+namespace FileSys {
+
+SDMC_Factory::SDMC_Factory(std::string sd_directory) : sd_directory(std::move(sd_directory)) {}
+
+ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& path) {
+ // Create the SD Card directory if it doesn't already exist.
+ if (!FileUtil::IsDirectory(sd_directory)) {
+ FileUtil::CreateFullPath(sd_directory);
+ }
+
+ auto archive = std::make_unique<Disk_FileSystem>(sd_directory);
+ return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
+}
+
+ResultCode SDMC_Factory::Format(const Path& path) {
+ LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
+ // TODO(Subv): Find the right error code for this
+ return ResultCode(-1);
+}
+
+ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const {
+ LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
+ // TODO(bunnei): Find the right error code for this
+ return ResultCode(-1);
+}
+
+} // namespace FileSys
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h
new file mode 100644
index 000000000..93becda25
--- /dev/null
+++ b/src/core/file_sys/sdmc_factory.h
@@ -0,0 +1,31 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include "common/common_types.h"
+#include "core/file_sys/filesystem.h"
+#include "core/hle/result.h"
+
+namespace FileSys {
+
+/// File system interface to the SDCard archive
+class SDMC_Factory final : public FileSystemFactory {
+public:
+ explicit SDMC_Factory(std::string sd_directory);
+
+ std::string GetName() const override {
+ return "SDMC_Factory";
+ }
+ ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
+ ResultCode Format(const Path& path) override;
+ ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
+
+private:
+ std::string sd_directory;
+};
+
+} // namespace FileSys
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index ef05955b9..945832e98 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -6,6 +6,7 @@
#include "common/file_util.h"
#include "core/file_sys/filesystem.h"
#include "core/file_sys/savedata_factory.h"
+#include "core/file_sys/sdmc_factory.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/filesystem/fsp_srv.h"
@@ -60,9 +61,13 @@ void RegisterFileSystems() {
filesystem_map.clear();
std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX);
+ std::string sd_directory = FileUtil::GetUserPath(D_SDMC_IDX);
auto savedata = std::make_unique<FileSys::SaveData_Factory>(std::move(nand_directory));
RegisterFileSystem(std::move(savedata), Type::SaveData);
+
+ auto sdcard = std::make_unique<FileSys::SDMC_Factory>(std::move(sd_directory));
+ RegisterFileSystem(std::move(sdcard), Type::SDMC);
}
void InstallInterfaces(SM::ServiceManager& service_manager) {
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 8d30e94a1..56d26146e 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -26,6 +26,7 @@ namespace FileSystem {
enum class Type {
RomFS = 1,
SaveData = 2,
+ SDMC = 3,
};
/**
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index e5ce41671..41b8cbfd2 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -5,6 +5,7 @@
#include <cinttypes>
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/file_sys/directory.h"
#include "core/file_sys/filesystem.h"
#include "core/file_sys/storage.h"
#include "core/hle/ipc_helpers.h"
@@ -151,14 +152,66 @@ private:
}
};
+class IDirectory final : public ServiceFramework<IDirectory> {
+public:
+ explicit IDirectory(std::unique_ptr<FileSys::DirectoryBackend>&& backend)
+ : ServiceFramework("IDirectory"), backend(std::move(backend)) {
+ static const FunctionInfo functions[] = {
+ {0, &IDirectory::Read, "Read"},
+ {1, &IDirectory::GetEntryCount, "GetEntryCount"},
+ };
+ RegisterHandlers(functions);
+ }
+
+private:
+ std::unique_ptr<FileSys::DirectoryBackend> backend;
+
+ void Read(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const u64 unk = rp.Pop<u64>();
+
+ LOG_DEBUG(Service_FS, "called, unk=0x%llx", unk);
+
+ // Calculate how many entries we can fit in the output buffer
+ u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
+
+ // Read the data from the Directory backend
+ std::vector<FileSys::Entry> entries(count_entries);
+ u64 read_entries = backend->Read(count_entries, entries.data());
+
+ // Convert the data into a byte array
+ std::vector<u8> output(entries.size() * sizeof(FileSys::Entry));
+ std::memcpy(output.data(), entries.data(), output.size());
+
+ // Write the data to memory
+ ctx.WriteBuffer(output);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(read_entries);
+ }
+
+ void GetEntryCount(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_FS, "called");
+
+ u64 count = backend->GetEntryCount();
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(count);
+ }
+};
+
class IFileSystem final : public ServiceFramework<IFileSystem> {
public:
explicit IFileSystem(std::unique_ptr<FileSys::FileSystemBackend>&& backend)
: ServiceFramework("IFileSystem"), backend(std::move(backend)) {
static const FunctionInfo functions[] = {
{0, &IFileSystem::CreateFile, "CreateFile"},
+ {2, &IFileSystem::CreateDirectory, "CreateDirectory"},
{7, &IFileSystem::GetEntryType, "GetEntryType"},
{8, &IFileSystem::OpenFile, "OpenFile"},
+ {9, &IFileSystem::OpenDirectory, "OpenDirectory"},
{10, &IFileSystem::Commit, "Commit"},
};
RegisterHandlers(functions);
@@ -182,6 +235,20 @@ public:
rb.Push(backend->CreateFile(name, size));
}
+ void CreateDirectory(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ auto file_buffer = ctx.ReadBuffer();
+ auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
+
+ std::string name(file_buffer.begin(), end);
+
+ LOG_DEBUG(Service_FS, "called directory %s", name.c_str());
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(backend->CreateDirectory(name));
+ }
+
void OpenFile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
@@ -208,6 +275,33 @@ public:
rb.PushIpcInterface<IFile>(std::move(file));
}
+ void OpenDirectory(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ auto file_buffer = ctx.ReadBuffer();
+ auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
+
+ std::string name(file_buffer.begin(), end);
+
+ // TODO(Subv): Implement this filter.
+ u32 filter_flags = rp.Pop<u32>();
+
+ LOG_DEBUG(Service_FS, "called directory %s filter %u", name.c_str(), filter_flags);
+
+ auto result = backend->OpenDirectory(name);
+ if (result.Failed()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result.Code());
+ return;
+ }
+
+ auto directory = std::move(result.Unwrap());
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IDirectory>(std::move(directory));
+ }
+
void GetEntryType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
@@ -274,10 +368,14 @@ void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) {
}
void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_FS, "(STUBBED) called");
+ LOG_DEBUG(Service_FS, "called");
- IPC::ResponseBuilder rb{ctx, 2};
+ FileSys::Path unused;
+ auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap();
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
}
void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 4846fe092..b224b89da 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -34,6 +34,8 @@
#include "core/hle/service/sm/controller.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/sockets/sockets.h"
+#include "core/hle/service/spl/module.h"
+#include "core/hle/service/ssl/ssl.h"
#include "core/hle/service/time/time.h"
#include "core/hle/service/vi/vi.h"
@@ -190,6 +192,8 @@ void Init() {
Nvidia::InstallInterfaces(*SM::g_service_manager);
PCTL::InstallInterfaces(*SM::g_service_manager);
Sockets::InstallInterfaces(*SM::g_service_manager);
+ SPL::InstallInterfaces(*SM::g_service_manager);
+ SSL::InstallInterfaces(*SM::g_service_manager);
Time::InstallInterfaces(*SM::g_service_manager);
VI::InstallInterfaces(*SM::g_service_manager, nv_flinger);
Set::InstallInterfaces(*SM::g_service_manager);
diff --git a/src/core/hle/service/spl/csrng.cpp b/src/core/hle/service/spl/csrng.cpp
new file mode 100644
index 000000000..cde05717a
--- /dev/null
+++ b/src/core/hle/service/spl/csrng.cpp
@@ -0,0 +1,18 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/spl/csrng.h"
+
+namespace Service {
+namespace SPL {
+
+CSRNG::CSRNG(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "csrng") {
+ static const FunctionInfo functions[] = {
+ {0, &CSRNG::GetRandomBytes, "GetRandomBytes"},
+ };
+ RegisterHandlers(functions);
+}
+
+} // namespace SPL
+} // namespace Service
diff --git a/src/core/hle/service/spl/csrng.h b/src/core/hle/service/spl/csrng.h
new file mode 100644
index 000000000..59ca794dd
--- /dev/null
+++ b/src/core/hle/service/spl/csrng.h
@@ -0,0 +1,18 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/spl/module.h"
+
+namespace Service {
+namespace SPL {
+
+class CSRNG final : public Module::Interface {
+public:
+ explicit CSRNG(std::shared_ptr<Module> module);
+};
+
+} // namespace SPL
+} // namespace Service
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
new file mode 100644
index 000000000..fc1bcd94c
--- /dev/null
+++ b/src/core/hle/service/spl/module.cpp
@@ -0,0 +1,42 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <cstdlib>
+#include <vector>
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/spl/csrng.h"
+#include "core/hle/service/spl/module.h"
+#include "core/hle/service/spl/spl.h"
+
+namespace Service {
+namespace SPL {
+
+Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
+ : ServiceFramework(name), module(std::move(module)) {}
+
+void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ size_t size = ctx.GetWriteBufferSize();
+
+ std::vector<u8> data(size);
+ std::generate(data.begin(), data.end(), std::rand);
+
+ ctx.WriteBuffer(data);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ LOG_DEBUG(Service_SPL, "called");
+}
+
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+ auto module = std::make_shared<Module>();
+ std::make_shared<CSRNG>(module)->InstallAsService(service_manager);
+ std::make_shared<SPL>(module)->InstallAsService(service_manager);
+}
+
+} // namespace SPL
+} // namespace Service
diff --git a/src/core/hle/service/spl/module.h b/src/core/hle/service/spl/module.h
new file mode 100644
index 000000000..12cdb2980
--- /dev/null
+++ b/src/core/hle/service/spl/module.h
@@ -0,0 +1,29 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace SPL {
+
+class Module final {
+public:
+ class Interface : public ServiceFramework<Interface> {
+ public:
+ Interface(std::shared_ptr<Module> module, const char* name);
+
+ void GetRandomBytes(Kernel::HLERequestContext& ctx);
+
+ protected:
+ std::shared_ptr<Module> module;
+ };
+};
+
+/// Registers all SPL services with the specified service manager.
+void InstallInterfaces(SM::ServiceManager& service_manager);
+
+} // namespace SPL
+} // namespace Service
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp
new file mode 100644
index 000000000..deab29b91
--- /dev/null
+++ b/src/core/hle/service/spl/spl.cpp
@@ -0,0 +1,41 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/spl/spl.h"
+
+namespace Service {
+namespace SPL {
+
+SPL::SPL(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "spl:") {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetConfig"},
+ {1, nullptr, "UserExpMod"},
+ {2, nullptr, "GenerateAesKek"},
+ {3, nullptr, "LoadAesKey"},
+ {4, nullptr, "GenerateAesKey"},
+ {5, nullptr, "SetConfig"},
+ {7, &SPL::GetRandomBytes, "GetRandomBytes"},
+ {9, nullptr, "LoadSecureExpModKey"},
+ {10, nullptr, "SecureExpMod"},
+ {11, nullptr, "IsDevelopment"},
+ {12, nullptr, "GenerateSpecificAesKey"},
+ {13, nullptr, "DecryptPrivk"},
+ {14, nullptr, "DecryptAesKey"},
+ {15, nullptr, "DecryptAesCtr"},
+ {16, nullptr, "ComputeCmac"},
+ {17, nullptr, "LoadRsaOaepKey"},
+ {18, nullptr, "UnwrapRsaOaepWrappedTitleKey"},
+ {19, nullptr, "LoadTitleKey"},
+ {20, nullptr, "UnwrapAesWrappedTitleKey"},
+ {21, nullptr, "LockAesEngine"},
+ {22, nullptr, "UnlockAesEngine"},
+ {23, nullptr, "GetSplWaitEvent"},
+ {24, nullptr, "SetSharedData"},
+ {25, nullptr, "GetSharedData"},
+ };
+ RegisterHandlers(functions);
+}
+
+} // namespace SPL
+} // namespace Service
diff --git a/src/core/hle/service/spl/spl.h b/src/core/hle/service/spl/spl.h
new file mode 100644
index 000000000..9fd6059af
--- /dev/null
+++ b/src/core/hle/service/spl/spl.h
@@ -0,0 +1,18 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/spl/module.h"
+
+namespace Service {
+namespace SPL {
+
+class SPL final : public Module::Interface {
+public:
+ explicit SPL(std::shared_ptr<Module> module);
+};
+
+} // namespace SPL
+} // namespace Service
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
new file mode 100644
index 000000000..afa8d5d79
--- /dev/null
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -0,0 +1,17 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/ssl/ssl.h"
+
+namespace Service {
+namespace SSL {
+
+SSL::SSL() : ServiceFramework("ssl") {}
+
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+ std::make_shared<SSL>()->InstallAsService(service_manager);
+}
+
+} // namespace SSL
+} // namespace Service
diff --git a/src/core/hle/service/ssl/ssl.h b/src/core/hle/service/ssl/ssl.h
new file mode 100644
index 000000000..645dad003
--- /dev/null
+++ b/src/core/hle/service/ssl/ssl.h
@@ -0,0 +1,22 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace SSL {
+
+class SSL final : public ServiceFramework<SSL> {
+public:
+ explicit SSL();
+ ~SSL() = default;
+};
+
+/// Registers all SSL services with the specified service manager.
+void InstallInterfaces(SM::ServiceManager& service_manager);
+
+} // namespace SSL
+} // namespace Service
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 0eca4e76e..d6469dd3d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -23,7 +23,6 @@
namespace Memory {
static std::array<u8, Memory::VRAM_SIZE> vram;
-static std::array<u8, Memory::N3DS_EXTRA_RAM_SIZE> n3ds_extra_ram;
static PageTable* current_page_table = nullptr;
@@ -247,7 +246,6 @@ u8* GetPhysicalPointer(PAddr address) {
{IO_AREA_PADDR, IO_AREA_SIZE},
{DSP_RAM_PADDR, DSP_RAM_SIZE},
{FCRAM_PADDR, FCRAM_N3DS_SIZE},
- {N3DS_EXTRA_RAM_PADDR, N3DS_EXTRA_RAM_SIZE},
};
const auto area =
@@ -286,9 +284,6 @@ u8* GetPhysicalPointer(PAddr address) {
}
ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
break;
- case N3DS_EXTRA_RAM_PADDR:
- target_pointer = n3ds_extra_ram.data() + offset_into_region;
- break;
default:
UNREACHABLE();
}
@@ -649,8 +644,6 @@ boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
} else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
return addr - IO_AREA_VADDR + IO_AREA_PADDR;
- } else if (addr >= N3DS_EXTRA_RAM_VADDR && addr < N3DS_EXTRA_RAM_VADDR_END) {
- return addr - N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_PADDR;
}
return boost::none;
@@ -677,8 +670,6 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
} else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
return addr - IO_AREA_PADDR + IO_AREA_VADDR;
- } else if (addr >= N3DS_EXTRA_RAM_PADDR && addr < N3DS_EXTRA_RAM_PADDR_END) {
- return addr - N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_VADDR;
}
return boost::none;
diff --git a/src/core/memory.h b/src/core/memory.h
index 3e2c3f23d..4b9c482fe 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -101,12 +101,6 @@ enum : PAddr {
VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
- /// New 3DS additional memory. Supposedly faster than regular FCRAM. Part of it can be used by
- /// applications and system modules if mapped via the ExHeader.
- N3DS_EXTRA_RAM_PADDR = 0x1F000000,
- N3DS_EXTRA_RAM_SIZE = 0x00400000, ///< New 3DS additional memory size (4MB)
- N3DS_EXTRA_RAM_PADDR_END = N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_SIZE,
-
/// DSP memory
DSP_RAM_PADDR = 0x1FF00000,
DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
@@ -122,7 +116,6 @@ enum : PAddr {
FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
- FCRAM_N3DS_PADDR_END = FCRAM_PADDR + FCRAM_N3DS_SIZE,
};
/// Virtual user-space memory regions
@@ -138,10 +131,6 @@ enum : VAddr {
LINEAR_HEAP_SIZE = 0x08000000,
LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
- /// Maps 1:1 to New 3DS additional memory
- N3DS_EXTRA_RAM_VADDR = 0x1E800000,
- N3DS_EXTRA_RAM_VADDR_END = N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_SIZE,
-
/// Maps 1:1 to the IO register area.
IO_AREA_VADDR = 0x1EC00000,
IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,