HLE/FS: Return the proper error codes when opening files.
This commit is contained in:
parent
4be40b7c81
commit
910871cc7c
7 changed files with 43 additions and 28 deletions
|
@ -76,9 +76,9 @@ public:
|
||||||
* Open a file specified by its path, using the specified mode
|
* Open a file specified by its path, using the specified mode
|
||||||
* @param path Path relative to the archive
|
* @param path Path relative to the archive
|
||||||
* @param mode Mode to open the file with
|
* @param mode Mode to open the file with
|
||||||
* @return Opened file, or nullptr
|
* @return Opened file, or error code
|
||||||
*/
|
*/
|
||||||
virtual std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const = 0;
|
virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a file specified by its path
|
* Delete a file specified by its path
|
||||||
|
|
|
@ -17,12 +17,13 @@
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const {
|
ResultVal<std::unique_ptr<FileBackend>> DiskArchive::OpenFile(const Path& path, const Mode mode) const {
|
||||||
LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
|
LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
|
||||||
auto file = Common::make_unique<DiskFile>(*this, path, mode);
|
auto file = Common::make_unique<DiskFile>(*this, path, mode);
|
||||||
if (!file->Open())
|
ResultCode result = file->Open();
|
||||||
return nullptr;
|
if (result.IsError())
|
||||||
return std::move(file);
|
return result;
|
||||||
|
return MakeResult<std::unique_ptr<FileBackend>>(std::move(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode DiskArchive::DeleteFile(const Path& path) const {
|
ResultCode DiskArchive::DeleteFile(const Path& path) const {
|
||||||
|
@ -103,25 +104,38 @@ DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode
|
||||||
this->mode.hex = mode.hex;
|
this->mode.hex = mode.hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskFile::Open() {
|
ResultCode DiskFile::Open() {
|
||||||
if (!mode.create_flag && !FileUtil::Exists(path)) {
|
if (FileUtil::IsDirectory(path))
|
||||||
LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str());
|
return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status);
|
||||||
return false;
|
|
||||||
|
// Specifying only the Create flag is invalid
|
||||||
|
if (mode.create_flag && !mode.read_flag && !mode.write_flag) {
|
||||||
|
return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mode_string;
|
if (!FileUtil::Exists(path)) {
|
||||||
if (mode.create_flag)
|
if (!mode.create_flag) {
|
||||||
mode_string = "w+";
|
LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str());
|
||||||
else if (mode.write_flag)
|
return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status);
|
||||||
mode_string = "r+"; // Files opened with Write access can be read from
|
} else {
|
||||||
|
// Create the file
|
||||||
|
FileUtil::CreateEmptyFile(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mode_string = "";
|
||||||
|
if (mode.write_flag)
|
||||||
|
mode_string += "r+"; // Files opened with Write access can be read from
|
||||||
else if (mode.read_flag)
|
else if (mode.read_flag)
|
||||||
mode_string = "r";
|
mode_string += "r";
|
||||||
|
|
||||||
// Open the file in binary mode, to avoid problems with CR/LF on Windows systems
|
// Open the file in binary mode, to avoid problems with CR/LF on Windows systems
|
||||||
mode_string += "b";
|
mode_string += "b";
|
||||||
|
|
||||||
file = Common::make_unique<FileUtil::IOFile>(path, mode_string.c_str());
|
file = Common::make_unique<FileUtil::IOFile>(path, mode_string.c_str());
|
||||||
return file->IsOpen();
|
if (file->IsOpen())
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
|
|
||||||
virtual std::string GetName() const override { return "DiskArchive: " + mount_point; }
|
virtual std::string GetName() const override { return "DiskArchive: " + mount_point; }
|
||||||
|
|
||||||
std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
|
ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const override;
|
||||||
ResultCode DeleteFile(const Path& path) const override;
|
ResultCode DeleteFile(const Path& path) const override;
|
||||||
bool RenameFile(const Path& src_path, const Path& dest_path) const override;
|
bool RenameFile(const Path& src_path, const Path& dest_path) const override;
|
||||||
bool DeleteDirectory(const Path& path) const override;
|
bool DeleteDirectory(const Path& path) const override;
|
||||||
|
@ -54,7 +54,7 @@ class DiskFile : public FileBackend {
|
||||||
public:
|
public:
|
||||||
DiskFile(const DiskArchive& archive, const Path& path, const Mode mode);
|
DiskFile(const DiskArchive& archive, const Path& path, const Mode mode);
|
||||||
|
|
||||||
bool Open() override;
|
ResultCode Open() override;
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
|
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
|
|
|
@ -21,9 +21,9 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the file
|
* Open the file
|
||||||
* @return true if the file opened correctly
|
* @return Result of the file operation
|
||||||
*/
|
*/
|
||||||
virtual bool Open() = 0;
|
virtual ResultCode Open() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read data from the file
|
* Read data from the file
|
||||||
|
|
|
@ -20,8 +20,8 @@ std::string IVFCArchive::GetName() const {
|
||||||
return "IVFC";
|
return "IVFC";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const {
|
ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path, const Mode mode) const {
|
||||||
return Common::make_unique<IVFCFile>(romfs_file, data_offset, data_size);
|
return MakeResult<std::unique_ptr<FileBackend>>(Common::make_unique<IVFCFile>(romfs_file, data_offset, data_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode IVFCArchive::DeleteFile(const Path& path) const {
|
ResultCode IVFCArchive::DeleteFile(const Path& path) const {
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
std::string GetName() const override;
|
std::string GetName() const override;
|
||||||
|
|
||||||
std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
|
ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const override;
|
||||||
ResultCode DeleteFile(const Path& path) const override;
|
ResultCode DeleteFile(const Path& path) const override;
|
||||||
bool RenameFile(const Path& src_path, const Path& dest_path) const override;
|
bool RenameFile(const Path& src_path, const Path& dest_path) const override;
|
||||||
bool DeleteDirectory(const Path& path) const override;
|
bool DeleteDirectory(const Path& path) const override;
|
||||||
|
@ -55,7 +55,7 @@ public:
|
||||||
IVFCFile(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
|
IVFCFile(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
|
||||||
: romfs_file(file), data_offset(offset), data_size(size) {}
|
: romfs_file(file), data_offset(offset), data_size(size) {}
|
||||||
|
|
||||||
bool Open() override { return true; }
|
ResultCode Open() override { return RESULT_SUCCESS; }
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
|
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
|
|
|
@ -307,13 +307,14 @@ ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_han
|
||||||
if (archive == nullptr)
|
if (archive == nullptr)
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
std::unique_ptr<FileSys::FileBackend> backend = archive->OpenFile(path, mode);
|
auto backend = archive->OpenFile(path, mode);
|
||||||
if (backend == nullptr) {
|
if (backend.Failed()) {
|
||||||
|
return backend.Code();
|
||||||
return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS,
|
return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS,
|
||||||
ErrorSummary::NotFound, ErrorLevel::Status);
|
ErrorSummary::NotFound, ErrorLevel::Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file = Kernel::SharedPtr<File>(new File(std::move(backend), path));
|
auto file = Kernel::SharedPtr<File>(new File(backend.MoveFrom(), path));
|
||||||
return MakeResult<Kernel::SharedPtr<File>>(std::move(file));
|
return MakeResult<Kernel::SharedPtr<File>>(std::move(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue