Merge pull request #381 from Subv/savedatacheck
Implemented the SaveDataCheck archive
This commit is contained in:
commit
031237e52c
@ -42,6 +42,7 @@
|
|||||||
#define SDMC_DIR "sdmc"
|
#define SDMC_DIR "sdmc"
|
||||||
#define EXTSAVEDATA_DIR "extsavedata"
|
#define EXTSAVEDATA_DIR "extsavedata"
|
||||||
#define SAVEDATA_DIR "savedata"
|
#define SAVEDATA_DIR "savedata"
|
||||||
|
#define SAVEDATACHECK_DIR "savedatacheck"
|
||||||
#define SYSDATA_DIR "sysdata"
|
#define SYSDATA_DIR "sysdata"
|
||||||
#define SYSSAVEDATA_DIR "syssavedata"
|
#define SYSSAVEDATA_DIR "syssavedata"
|
||||||
#define SHADERCACHE_DIR "shader_cache"
|
#define SHADERCACHE_DIR "shader_cache"
|
||||||
|
@ -678,6 +678,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
|
|||||||
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
|
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
|
||||||
paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
|
paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
|
||||||
paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
|
paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
|
||||||
|
paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP;
|
||||||
paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP;
|
paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP;
|
||||||
paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
|
paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
|
||||||
paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
|
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
|
|||||||
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
|
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
|
||||||
paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
|
paths[D_EXTSAVEDATA] = paths[D_USER_IDX] + EXTSAVEDATA_DIR DIR_SEP;
|
||||||
paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
|
paths[D_SAVEDATA_IDX] = paths[D_USER_IDX] + SAVEDATA_DIR DIR_SEP;
|
||||||
|
paths[D_SAVEDATACHECK_IDX] = paths[D_USER_IDX] + SAVEDATACHECK_DIR DIR_SEP;
|
||||||
paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
|
paths[D_SYSSAVEDATA_IDX] = paths[D_USER_IDX] + SYSSAVEDATA_DIR DIR_SEP;
|
||||||
paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
|
paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
|
||||||
paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
|
paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
|
||||||
|
@ -29,6 +29,7 @@ enum {
|
|||||||
D_SDMC_IDX,
|
D_SDMC_IDX,
|
||||||
D_EXTSAVEDATA,
|
D_EXTSAVEDATA,
|
||||||
D_SAVEDATA_IDX,
|
D_SAVEDATA_IDX,
|
||||||
|
D_SAVEDATACHECK_IDX,
|
||||||
D_SYSDATA_IDX,
|
D_SYSDATA_IDX,
|
||||||
D_SYSSAVEDATA_IDX,
|
D_SYSSAVEDATA_IDX,
|
||||||
D_HIRESTEXTURES_IDX,
|
D_HIRESTEXTURES_IDX,
|
||||||
|
@ -20,11 +20,11 @@ set(SRCS
|
|||||||
file_sys/archive_extsavedata.cpp
|
file_sys/archive_extsavedata.cpp
|
||||||
file_sys/archive_romfs.cpp
|
file_sys/archive_romfs.cpp
|
||||||
file_sys/archive_savedata.cpp
|
file_sys/archive_savedata.cpp
|
||||||
|
file_sys/archive_savedatacheck.cpp
|
||||||
file_sys/archive_sdmc.cpp
|
file_sys/archive_sdmc.cpp
|
||||||
file_sys/archive_systemsavedata.cpp
|
file_sys/archive_systemsavedata.cpp
|
||||||
file_sys/disk_archive.cpp
|
file_sys/disk_archive.cpp
|
||||||
file_sys/file_romfs.cpp
|
file_sys/ivfc_archive.cpp
|
||||||
file_sys/directory_romfs.cpp
|
|
||||||
hle/kernel/address_arbiter.cpp
|
hle/kernel/address_arbiter.cpp
|
||||||
hle/kernel/event.cpp
|
hle/kernel/event.cpp
|
||||||
hle/kernel/kernel.cpp
|
hle/kernel/kernel.cpp
|
||||||
@ -108,13 +108,13 @@ set(HEADERS
|
|||||||
file_sys/archive_extsavedata.h
|
file_sys/archive_extsavedata.h
|
||||||
file_sys/archive_romfs.h
|
file_sys/archive_romfs.h
|
||||||
file_sys/archive_savedata.h
|
file_sys/archive_savedata.h
|
||||||
|
file_sys/archive_savedatacheck.h
|
||||||
file_sys/archive_sdmc.h
|
file_sys/archive_sdmc.h
|
||||||
file_sys/archive_systemsavedata.h
|
file_sys/archive_systemsavedata.h
|
||||||
file_sys/disk_archive.h
|
file_sys/disk_archive.h
|
||||||
file_sys/file_backend.h
|
file_sys/file_backend.h
|
||||||
file_sys/file_romfs.h
|
file_sys/ivfc_archive.h
|
||||||
file_sys/directory_backend.h
|
file_sys/directory_backend.h
|
||||||
file_sys/directory_romfs.h
|
|
||||||
hle/kernel/address_arbiter.h
|
hle/kernel/address_arbiter.h
|
||||||
hle/kernel/event.h
|
hle/kernel/event.h
|
||||||
hle/kernel/kernel.h
|
hle/kernel/kernel.h
|
||||||
|
@ -88,6 +88,7 @@ public:
|
|||||||
const std::string DebugStr() const {
|
const std::string DebugStr() const {
|
||||||
switch (GetType()) {
|
switch (GetType()) {
|
||||||
case Invalid:
|
case Invalid:
|
||||||
|
default:
|
||||||
return "[Invalid]";
|
return "[Invalid]";
|
||||||
case Empty:
|
case Empty:
|
||||||
return "[Empty]";
|
return "[Empty]";
|
||||||
@ -117,6 +118,7 @@ public:
|
|||||||
return {};
|
return {};
|
||||||
case Invalid:
|
case Invalid:
|
||||||
case Binary:
|
case Binary:
|
||||||
|
default:
|
||||||
// TODO(yuriks): Add assert
|
// TODO(yuriks): Add assert
|
||||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
|
LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
|
||||||
return {};
|
return {};
|
||||||
@ -159,6 +161,7 @@ public:
|
|||||||
case Empty:
|
case Empty:
|
||||||
return {};
|
return {};
|
||||||
case Invalid:
|
case Invalid:
|
||||||
|
default:
|
||||||
// TODO(yuriks): Add assert
|
// TODO(yuriks): Add assert
|
||||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
|
LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
|
||||||
return {};
|
return {};
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/file_util.h"
|
||||||
#include "common/make_unique.h"
|
#include "common/make_unique.h"
|
||||||
|
|
||||||
#include "core/file_sys/archive_romfs.h"
|
#include "core/file_sys/archive_romfs.h"
|
||||||
#include "core/file_sys/directory_romfs.h"
|
|
||||||
#include "core/file_sys/file_romfs.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// FileSys namespace
|
// FileSys namespace
|
||||||
@ -23,48 +22,4 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
|
|
||||||
return Common::make_unique<File_RomFS>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Archive_RomFS::DeleteFile(const Path& path) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Archive_RomFS::DeleteDirectory(const Path& path) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS.");
|
|
||||||
// TODO: Verify error code
|
|
||||||
return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Archive_RomFS::CreateDirectory(const Path& path) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const {
|
|
||||||
return Common::make_unique<Directory_RomFS>();
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode Archive_RomFS::Format(const Path& path) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to format ROMFS.");
|
|
||||||
return UnimplementedFunction(ErrorModule::FS);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "core/file_sys/archive_backend.h"
|
#include "core/file_sys/ivfc_archive.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -17,82 +17,12 @@
|
|||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
/// File system interface to the RomFS archive
|
/// File system interface to the RomFS archive
|
||||||
class Archive_RomFS final : public ArchiveBackend {
|
class Archive_RomFS final : public IVFCArchive {
|
||||||
public:
|
public:
|
||||||
Archive_RomFS(const Loader::AppLoader& app_loader);
|
Archive_RomFS(const Loader::AppLoader& app_loader);
|
||||||
|
|
||||||
std::string GetName() const override { return "RomFS"; }
|
std::string GetName() const override { return "RomFS"; }
|
||||||
|
ResultCode Open(const Path& path) override { return RESULT_SUCCESS; }
|
||||||
/**
|
|
||||||
* Open a file specified by its path, using the specified mode
|
|
||||||
* @param path Path relative to the archive
|
|
||||||
* @param mode Mode to open the file with
|
|
||||||
* @return Opened file, or nullptr
|
|
||||||
*/
|
|
||||||
std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a file specified by its path
|
|
||||||
* @param path Path relative to the archive
|
|
||||||
* @return Whether the file could be deleted
|
|
||||||
*/
|
|
||||||
bool DeleteFile(const Path& path) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rename a File specified by its path
|
|
||||||
* @param src_path Source path relative to the archive
|
|
||||||
* @param dest_path Destination path relative to the archive
|
|
||||||
* @return Whether rename succeeded
|
|
||||||
*/
|
|
||||||
bool RenameFile(const Path& src_path, const Path& dest_path) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a directory specified by its path
|
|
||||||
* @param path Path relative to the archive
|
|
||||||
* @return Whether the directory could be deleted
|
|
||||||
*/
|
|
||||||
bool DeleteDirectory(const Path& path) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a file specified by its path
|
|
||||||
* @param path Path relative to the Archive
|
|
||||||
* @param size The size of the new file, filled with zeroes
|
|
||||||
* @return File creation result code
|
|
||||||
*/
|
|
||||||
ResultCode CreateFile(const Path& path, u32 size) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a directory specified by its path
|
|
||||||
* @param path Path relative to the archive
|
|
||||||
* @return Whether the directory could be created
|
|
||||||
*/
|
|
||||||
bool CreateDirectory(const Path& path) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rename a Directory specified by its path
|
|
||||||
* @param src_path Source path relative to the archive
|
|
||||||
* @param dest_path Destination path relative to the archive
|
|
||||||
* @return Whether rename succeeded
|
|
||||||
*/
|
|
||||||
bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a directory specified by its path
|
|
||||||
* @param path Path relative to the archive
|
|
||||||
* @return Opened directory, or nullptr
|
|
||||||
*/
|
|
||||||
std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
|
|
||||||
|
|
||||||
ResultCode Open(const Path& path) override {
|
|
||||||
return RESULT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode Format(const Path& path) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class File_RomFS;
|
|
||||||
|
|
||||||
std::vector<u8> raw_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
41
src/core/file_sys/archive_savedatacheck.cpp
Normal file
41
src/core/file_sys/archive_savedatacheck.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2014 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/file_util.h"
|
||||||
|
|
||||||
|
#include "core/file_sys/archive_savedatacheck.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// FileSys namespace
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode Archive_SaveDataCheck::Open(const Path& path) {
|
||||||
|
// TODO(Subv): We should not be overwriting raw_data everytime this function is called,
|
||||||
|
// but until we use factory classes to create the archives at runtime instead of creating them beforehand
|
||||||
|
// and allow multiple archives of the same type to be open at the same time without clobbering each other,
|
||||||
|
// we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed.
|
||||||
|
// There are a number of problems with this, for example opening a file in this archive, then opening
|
||||||
|
// this archive again with a different path, will corrupt the previously open file.
|
||||||
|
auto vec = path.AsBinary();
|
||||||
|
const u32* data = reinterpret_cast<u32*>(vec.data());
|
||||||
|
std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]);
|
||||||
|
FileUtil::IOFile file(file_path, "rb");
|
||||||
|
|
||||||
|
std::fill(raw_data.begin(), raw_data.end(), 0);
|
||||||
|
|
||||||
|
if (!file.IsOpen()) {
|
||||||
|
return ResultCode(-1); // TODO(Subv): Find the right error code
|
||||||
|
}
|
||||||
|
auto size = file.GetSize();
|
||||||
|
raw_data.resize(size);
|
||||||
|
file.ReadBytes(raw_data.data(), size);
|
||||||
|
file.Close();
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
31
src/core/file_sys/archive_savedatacheck.h
Normal file
31
src/core/file_sys/archive_savedatacheck.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2014 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
#include "core/file_sys/ivfc_archive.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// FileSys namespace
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
/// File system interface to the SaveDataCheck archive
|
||||||
|
class Archive_SaveDataCheck final : public IVFCArchive {
|
||||||
|
public:
|
||||||
|
Archive_SaveDataCheck(const std::string& mount_point);
|
||||||
|
|
||||||
|
std::string GetName() const override { return "SaveDataCheck"; }
|
||||||
|
ResultCode Open(const Path& path) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mount_point;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
@ -1,32 +0,0 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
#include "core/file_sys/directory_romfs.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FileSys namespace
|
|
||||||
|
|
||||||
namespace FileSys {
|
|
||||||
|
|
||||||
Directory_RomFS::Directory_RomFS() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Directory_RomFS::~Directory_RomFS() {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Directory_RomFS::Open() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 Directory_RomFS::Read(const u32 count, Entry* entries) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Directory_RomFS::Close() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace FileSys
|
|
@ -1,43 +0,0 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
#include "core/file_sys/directory_backend.h"
|
|
||||||
#include "core/loader/loader.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FileSys namespace
|
|
||||||
|
|
||||||
namespace FileSys {
|
|
||||||
|
|
||||||
class Directory_RomFS final : public DirectoryBackend {
|
|
||||||
public:
|
|
||||||
Directory_RomFS();
|
|
||||||
~Directory_RomFS() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the directory
|
|
||||||
* @return true if the directory opened correctly
|
|
||||||
*/
|
|
||||||
bool Open() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List files contained in the directory
|
|
||||||
* @param count Number of entries to return at once in entries
|
|
||||||
* @param entries Buffer to read data into
|
|
||||||
* @return Number of entries listed
|
|
||||||
*/
|
|
||||||
u32 Read(const u32 count, Entry* entries) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the directory
|
|
||||||
* @return true if the directory closed correctly
|
|
||||||
*/
|
|
||||||
bool Close() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FileSys
|
|
@ -1,43 +0,0 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
#include "core/file_sys/file_romfs.h"
|
|
||||||
#include "core/file_sys/archive_romfs.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FileSys namespace
|
|
||||||
|
|
||||||
namespace FileSys {
|
|
||||||
|
|
||||||
bool File_RomFS::Open() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
|
|
||||||
LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
|
|
||||||
memcpy(buffer, &archive->raw_data[(u32)offset], length);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to write to ROMFS.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t File_RomFS::GetSize() const {
|
|
||||||
return sizeof(u8) * archive->raw_data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File_RomFS::SetSize(const u64 size) const {
|
|
||||||
LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool File_RomFS::Close() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace FileSys
|
|
@ -1,73 +0,0 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
#include "core/file_sys/file_backend.h"
|
|
||||||
#include "core/loader/loader.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FileSys namespace
|
|
||||||
|
|
||||||
namespace FileSys {
|
|
||||||
|
|
||||||
class Archive_RomFS;
|
|
||||||
|
|
||||||
class File_RomFS final : public FileBackend {
|
|
||||||
public:
|
|
||||||
File_RomFS(const Archive_RomFS* archive) : archive(archive) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the file
|
|
||||||
* @return true if the file opened correctly
|
|
||||||
*/
|
|
||||||
bool Open() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read data from the file
|
|
||||||
* @param offset Offset in bytes to start reading data from
|
|
||||||
* @param length Length in bytes of data to read from file
|
|
||||||
* @param buffer Buffer to read data into
|
|
||||||
* @return Number of bytes read
|
|
||||||
*/
|
|
||||||
size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to the file
|
|
||||||
* @param offset Offset in bytes to start writing data to
|
|
||||||
* @param length Length in bytes of data to write to file
|
|
||||||
* @param flush The flush parameters (0 == do not flush)
|
|
||||||
* @param buffer Buffer to read data from
|
|
||||||
* @return Number of bytes written
|
|
||||||
*/
|
|
||||||
size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the file in bytes
|
|
||||||
* @return Size of the file in bytes
|
|
||||||
*/
|
|
||||||
size_t GetSize() const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the size of the file in bytes
|
|
||||||
* @param size New size of the file
|
|
||||||
* @return true if successful
|
|
||||||
*/
|
|
||||||
bool SetSize(const u64 size) const override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the file
|
|
||||||
* @return true if the file closed correctly
|
|
||||||
*/
|
|
||||||
bool Close() const override;
|
|
||||||
|
|
||||||
void Flush() const override { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const Archive_RomFS* archive;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FileSys
|
|
88
src/core/file_sys/ivfc_archive.cpp
Normal file
88
src/core/file_sys/ivfc_archive.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Copyright 2014 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/file_util.h"
|
||||||
|
#include "common/make_unique.h"
|
||||||
|
|
||||||
|
#include "core/file_sys/ivfc_archive.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// FileSys namespace
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
IVFCArchive::IVFCArchive() {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const {
|
||||||
|
return Common::make_unique<IVFCFile>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IVFCArchive::DeleteFile(const Path& path) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IVFCArchive::DeleteDirectory(const Path& path) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str());
|
||||||
|
// TODO: Verify error code
|
||||||
|
return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IVFCArchive::CreateDirectory(const Path& path) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) const {
|
||||||
|
return Common::make_unique<IVFCDirectory>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode IVFCArchive::Format(const Path& path) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str());
|
||||||
|
// TODO: Verify error code
|
||||||
|
return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const {
|
||||||
|
LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
|
||||||
|
memcpy(buffer, &archive->raw_data[(u32)offset], length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IVFCFile::GetSize() const {
|
||||||
|
return sizeof(u8) * archive->raw_data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IVFCFile::SetSize(const u64 size) const {
|
||||||
|
LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
66
src/core/file_sys/ivfc_archive.h
Normal file
66
src/core/file_sys/ivfc_archive.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2014 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
#include "core/file_sys/archive_backend.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// FileSys namespace
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper which implements an interface to deal with IVFC images used in some archives
|
||||||
|
* This should be subclassed by concrete archive types, which will provide the
|
||||||
|
* input data (load the raw IVFC archive) and override any required methods
|
||||||
|
*/
|
||||||
|
class IVFCArchive : public ArchiveBackend {
|
||||||
|
public:
|
||||||
|
IVFCArchive();
|
||||||
|
|
||||||
|
std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
|
||||||
|
bool DeleteFile(const Path& path) const override;
|
||||||
|
bool RenameFile(const Path& src_path, const Path& dest_path) const override;
|
||||||
|
bool DeleteDirectory(const Path& path) const override;
|
||||||
|
ResultCode CreateFile(const Path& path, u32 size) const override;
|
||||||
|
bool CreateDirectory(const Path& path) const override;
|
||||||
|
bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
|
||||||
|
std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
|
||||||
|
ResultCode Format(const Path& path) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class IVFCFile;
|
||||||
|
std::vector<u8> raw_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IVFCFile : public FileBackend {
|
||||||
|
public:
|
||||||
|
IVFCFile(const IVFCArchive* archive) : archive(archive) {}
|
||||||
|
|
||||||
|
bool Open() override { return true; }
|
||||||
|
size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
|
||||||
|
size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
|
||||||
|
size_t GetSize() const override;
|
||||||
|
bool SetSize(const u64 size) const override;
|
||||||
|
bool Close() const override { return false; }
|
||||||
|
void Flush() const override { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const IVFCArchive* archive;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IVFCDirectory : public DirectoryBackend {
|
||||||
|
public:
|
||||||
|
bool Open() override { return false; }
|
||||||
|
u32 Read(const u32 count, Entry* entries) override { return 0; }
|
||||||
|
bool Close() const override { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
@ -10,9 +10,11 @@
|
|||||||
#include "common/make_unique.h"
|
#include "common/make_unique.h"
|
||||||
#include "common/math_util.h"
|
#include "common/math_util.h"
|
||||||
|
|
||||||
#include "core/file_sys/archive_savedata.h"
|
|
||||||
#include "core/file_sys/archive_extsavedata.h"
|
|
||||||
#include "core/file_sys/archive_backend.h"
|
#include "core/file_sys/archive_backend.h"
|
||||||
|
#include "core/file_sys/archive_extsavedata.h"
|
||||||
|
#include "core/file_sys/archive_romfs.h"
|
||||||
|
#include "core/file_sys/archive_savedata.h"
|
||||||
|
#include "core/file_sys/archive_savedatacheck.h"
|
||||||
#include "core/file_sys/archive_sdmc.h"
|
#include "core/file_sys/archive_sdmc.h"
|
||||||
#include "core/file_sys/directory_backend.h"
|
#include "core/file_sys/directory_backend.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
@ -50,6 +52,9 @@ enum class FileCommand : u32 {
|
|||||||
SetAttributes = 0x08070040,
|
SetAttributes = 0x08070040,
|
||||||
Close = 0x08080000,
|
Close = 0x08080000,
|
||||||
Flush = 0x08090000,
|
Flush = 0x08090000,
|
||||||
|
SetPriority = 0x080A0040,
|
||||||
|
GetPriority = 0x080B0000,
|
||||||
|
OpenLinkFile = 0x080C0000,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Command to access directory
|
// Command to access directory
|
||||||
@ -75,12 +80,13 @@ public:
|
|||||||
class File : public Kernel::Session {
|
class File : public Kernel::Session {
|
||||||
public:
|
public:
|
||||||
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
|
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
|
||||||
: path(path), backend(std::move(backend)) {
|
: path(path), backend(std::move(backend)), priority(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetName() const override { return "Path: " + path.DebugStr(); }
|
std::string GetName() const override { return "Path: " + path.DebugStr(); }
|
||||||
|
|
||||||
FileSys::Path path; ///< Path of the file
|
FileSys::Path path; ///< Path of the file
|
||||||
|
u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
|
||||||
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
|
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
|
||||||
|
|
||||||
ResultVal<bool> SyncRequest() override {
|
ResultVal<bool> SyncRequest() override {
|
||||||
@ -145,6 +151,27 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case FileCommand::OpenLinkFile:
|
||||||
|
{
|
||||||
|
LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
|
||||||
|
cmd_buff[3] = GetHandle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FileCommand::SetPriority:
|
||||||
|
{
|
||||||
|
priority = cmd_buff[1];
|
||||||
|
LOG_TRACE(Service_FS, "SetPriority %u", priority);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FileCommand::GetPriority:
|
||||||
|
{
|
||||||
|
cmd_buff[2] = priority;
|
||||||
|
LOG_TRACE(Service_FS, "GetPriority");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Unknown command...
|
// Unknown command...
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
|
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
|
||||||
@ -327,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
|
|||||||
ErrorSummary::Canceled, ErrorLevel::Status);
|
ErrorSummary::Canceled, ErrorLevel::Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) {
|
ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) {
|
||||||
Archive* archive = GetArchive(archive_handle);
|
Archive* archive = GetArchive(archive_handle);
|
||||||
if (archive == nullptr)
|
if (archive == nullptr)
|
||||||
return InvalidHandle(ErrorModule::FS);
|
return InvalidHandle(ErrorModule::FS);
|
||||||
@ -435,6 +462,11 @@ void ArchiveInit() {
|
|||||||
else
|
else
|
||||||
LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
|
LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
|
||||||
sharedextsavedata_directory.c_str());
|
sharedextsavedata_directory.c_str());
|
||||||
|
|
||||||
|
// Create the SaveDataCheck archive, basically a small variation of the RomFS archive
|
||||||
|
std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX);
|
||||||
|
auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory);
|
||||||
|
CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shutdown archives
|
/// Shutdown archives
|
||||||
|
@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 {
|
|||||||
SystemSaveData = 0x00000008,
|
SystemSaveData = 0x00000008,
|
||||||
SDMC = 0x00000009,
|
SDMC = 0x00000009,
|
||||||
SDMCWriteOnly = 0x0000000A,
|
SDMCWriteOnly = 0x0000000A,
|
||||||
|
SaveDataCheck = 0x2345678A,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef u64 ArchiveHandle;
|
typedef u64 ArchiveHandle;
|
||||||
@ -90,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
|
|||||||
* @param file_size The size of the new file, filled with zeroes
|
* @param file_size The size of the new file, filled with zeroes
|
||||||
* @return File creation result code
|
* @return File creation result code
|
||||||
*/
|
*/
|
||||||
ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size);
|
ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Directory from an Archive
|
* Create a Directory from an Archive
|
||||||
|
Loading…
Reference in New Issue
Block a user