From 20d2ed09502f41519beb435a1300f2a57995c651 Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 7 Dec 2014 14:40:27 -0800 Subject: [PATCH] Make OpenDirectory fail if the directory doesn't exist This is in line with what the hardware itself does. It does this by splitting the initial directory opening into Directory.Open(), which will return false if a stat fails. Then, Archive::OpenDirectory will return nullptr, and archive.cpp will return an error code . --- src/core/file_sys/archive_sdmc.cpp | 2 ++ src/core/file_sys/directory.h | 6 ++++++ src/core/file_sys/directory_romfs.cpp | 4 ++++ src/core/file_sys/directory_romfs.h | 6 ++++++ src/core/file_sys/directory_sdmc.cpp | 13 ++++++++++--- src/core/file_sys/directory_sdmc.h | 7 +++++++ src/core/hle/kernel/archive.cpp | 5 +++++ 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 169ab0f1cd..fc0b9b72d3 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -100,6 +100,8 @@ bool Archive_SDMC::RenameDirectory(const FileSys::Path& src_path, const FileSys: std::unique_ptr Archive_SDMC::OpenDirectory(const Path& path) const { DEBUG_LOG(FILESYS, "called path=%s", path.DebugStr().c_str()); Directory_SDMC* directory = new Directory_SDMC(this, path); + if (!directory->Open()) + return nullptr; return std::unique_ptr(directory); } diff --git a/src/core/file_sys/directory.h b/src/core/file_sys/directory.h index e104313374..1bb4101d6d 100644 --- a/src/core/file_sys/directory.h +++ b/src/core/file_sys/directory.h @@ -41,6 +41,12 @@ public: Directory() { } virtual ~Directory() { } + /** + * Open the directory + * @return true if the directory opened correctly + */ + virtual bool Open() = 0; + /** * List files contained in the directory * @param count Number of entries to return at once in entries diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp index 4e8f4c04db..e6d571391f 100644 --- a/src/core/file_sys/directory_romfs.cpp +++ b/src/core/file_sys/directory_romfs.cpp @@ -17,6 +17,10 @@ Directory_RomFS::Directory_RomFS() { Directory_RomFS::~Directory_RomFS() { } +bool Directory_RomFS::Open() { + return false; +} + /** * List files contained in the directory * @param count Number of entries to return at once in entries diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h index 4b71c4b13e..e2944099e1 100644 --- a/src/core/file_sys/directory_romfs.h +++ b/src/core/file_sys/directory_romfs.h @@ -19,6 +19,12 @@ 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 diff --git a/src/core/file_sys/directory_sdmc.cpp b/src/core/file_sys/directory_sdmc.cpp index 60a197ce98..0f156a1274 100644 --- a/src/core/file_sys/directory_sdmc.cpp +++ b/src/core/file_sys/directory_sdmc.cpp @@ -19,15 +19,22 @@ Directory_SDMC::Directory_SDMC(const Archive_SDMC* archive, const Path& path) { // TODO(Link Mauve): normalize path into an absolute path without "..", it can currently bypass // the root directory we set while opening the archive. // For example, opening /../../usr/bin can give the emulated program your installed programs. - std::string absolute_path = archive->GetMountPoint() + path.AsString(); - FileUtil::ScanDirectoryTree(absolute_path, directory); - children_iterator = directory.children.begin(); + this->path = archive->GetMountPoint() + path.AsString(); + } Directory_SDMC::~Directory_SDMC() { Close(); } +bool Directory_SDMC::Open() { + if (!FileUtil::IsDirectory(path)) + return false; + FileUtil::ScanDirectoryTree(path, directory); + children_iterator = directory.children.begin(); + return true; +} + /** * List files contained in the directory * @param count Number of entries to return at once in entries diff --git a/src/core/file_sys/directory_sdmc.h b/src/core/file_sys/directory_sdmc.h index 4520d04011..4c08b0d61f 100644 --- a/src/core/file_sys/directory_sdmc.h +++ b/src/core/file_sys/directory_sdmc.h @@ -22,6 +22,12 @@ public: Directory_SDMC(const Archive_SDMC* archive, const Path& path); ~Directory_SDMC() 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 @@ -37,6 +43,7 @@ public: bool Close() const override; private: + std::string path; u32 total_entries_in_directory; FileUtil::FSTEntry directory; diff --git a/src/core/hle/kernel/archive.cpp b/src/core/hle/kernel/archive.cpp index 647f0dea94..a875fa7ff3 100644 --- a/src/core/hle/kernel/archive.cpp +++ b/src/core/hle/kernel/archive.cpp @@ -421,6 +421,11 @@ ResultVal OpenDirectoryFromArchive(Handle archive_handle, const FileSys: directory->path = path; directory->backend = archive->backend->OpenDirectory(path); + if (!directory->backend) { + return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, + ErrorSummary::NotFound, ErrorLevel::Permanent); + } + return MakeResult(handle); }