diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp index 46f22085e5..fb47eefa9d 100644 --- a/Core/FileSystems/BlobFileSystem.cpp +++ b/Core/FileSystems/BlobFileSystem.cpp @@ -30,9 +30,11 @@ void BlobFileSystem::DoState(PointerWrap &p) { // Not used in real emulation. } -std::vector BlobFileSystem::GetDirListing(std::string path) { +std::vector BlobFileSystem::GetDirListing(const std::string &path, bool *exists) { std::vector listing; listing.push_back(GetFileInfo(alias_)); + if (exists) + *exists = true; return listing; } diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index f45576d6a7..6def55870d 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -34,7 +34,7 @@ public: ~BlobFileSystem(); void DoState(PointerWrap &p) override; - std::vector GetDirListing(std::string path) override; + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override; int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override; void CloseFile(u32 handle) override; size_t ReadFile(u32 handle, u8 *pointer, s64 size) override; diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 0a2205a8d5..cf2ff0c8d9 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -789,7 +789,7 @@ bool DirectoryFileSystem::ComputeRecursiveDirSizeIfFast(const std::string &path, } } -std::vector DirectoryFileSystem::GetDirListing(std::string path) { +std::vector DirectoryFileSystem::GetDirListing(const std::string &path, bool *exists) { std::vector myVector; std::vector files; @@ -798,14 +798,19 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { if (!File::GetFilesInDir(localPath, &files, nullptr, flags)) { // TODO: Case sensitivity should be checked on a file system basis, right? #if HOST_IS_CASE_SENSITIVE - if (FixPathCase(basePath, path, FPC_FILE_MUST_EXIST)) { + std::string fixedPath = path; + if (FixPathCase(basePath, fixedPath, FPC_FILE_MUST_EXIST)) { // May have failed due to case sensitivity, try again - localPath = GetLocalPath(path); + localPath = GetLocalPath(fixedPath); if (!File::GetFilesInDir(localPath, &files, nullptr, 0)) { + if (exists) + *exists = false; return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs()); } } #else + if (exists) + *exists = false; return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs()); #endif } @@ -835,6 +840,7 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { entry.type = FILETYPE_NORMAL; } entry.access = file.access; + entry.exists = file.exists; localtime_r((time_t*)&file.atime, &entry.atime); localtime_r((time_t*)&file.ctime, &entry.ctime); @@ -843,6 +849,8 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { myVector.push_back(entry); } + if (exists) + *exists = true; return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs()); } @@ -1073,9 +1081,11 @@ size_t VFSFileSystem::SeekFile(u32 handle, s32 position, FileMove type) { } } -std::vector VFSFileSystem::GetDirListing(std::string path) { +std::vector VFSFileSystem::GetDirListing(const std::string &path, bool *exists) { std::vector myVector; // TODO + if (exists) + *exists = false; return myVector; } diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index 779325ed65..5edfa9a1a3 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -65,7 +65,7 @@ public: void CloseAll(); void DoState(PointerWrap &p) override; - std::vector GetDirListing(std::string path) override; + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override; int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override; void CloseFile(u32 handle) override; size_t ReadFile(u32 handle, u8 *pointer, s64 size) override; @@ -111,7 +111,7 @@ public: ~VFSFileSystem(); void DoState(PointerWrap &p) override; - std::vector GetDirListing(std::string path) override; + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override; int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override; void CloseFile(u32 handle) override; size_t ReadFile(u32 handle, u8 *pointer, s64 size) override; diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 87c87ae569..350b97cd8f 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -118,7 +118,7 @@ public: virtual ~IFileSystem() {} virtual void DoState(PointerWrap &p) = 0; - virtual std::vector GetDirListing(std::string path) = 0; + virtual std::vector GetDirListing(const std::string &path, bool *exists = nullptr) = 0; virtual int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) = 0; virtual void CloseFile(u32 handle) = 0; virtual size_t ReadFile(u32 handle, u8 *pointer, s64 size) = 0; @@ -143,7 +143,12 @@ public: class EmptyFileSystem : public IFileSystem { public: virtual void DoState(PointerWrap &p) override {} - std::vector GetDirListing(std::string path) override {std::vector vec; return vec;} + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override { + if (exists) + *exists = false; + std::vector vec; + return vec; + } int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override {return SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;} void CloseFile(u32 handle) override {} size_t ReadFile(u32 handle, u8 *pointer, s64 size) override {return 0;} diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 0d57bf2848..f52bc947c2 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -631,11 +631,14 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { return x; } -std::vector ISOFileSystem::GetDirListing(std::string path) { +std::vector ISOFileSystem::GetDirListing(const std::string &path, bool *exists) { std::vector myVector; TreeEntry *entry = GetFromPath(path); - if (!entry) + if (!entry) { + if (exists) + *exists = false; return myVector; + } const std::string dot("."); const std::string dotdot(".."); @@ -651,6 +654,7 @@ std::vector ISOFileSystem::GetDirListing(std::string path) { x.name = e->name; // Strangely, it seems to be executable even for files. x.access = 0555; + x.exists = true; x.size = e->size; x.type = e->isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; x.isOnSectorSystem = true; @@ -659,6 +663,8 @@ std::vector ISOFileSystem::GetDirListing(std::string path) { x.numSectors = (u32)((e->size + sectorSize - 1) / sectorSize); myVector.push_back(x); } + if (exists) + *exists = true; return myVector; } diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 608fa444e0..c7813bf1ac 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -33,7 +33,7 @@ public: ~ISOFileSystem(); void DoState(PointerWrap &p) override; - std::vector GetDirListing(std::string path) override; + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override; int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override; void CloseFile(u32 handle) override; size_t ReadFile(u32 handle, u8 *pointer, s64 size) override; @@ -110,7 +110,11 @@ public: isoFileSystem_->DoState(p); } - std::vector GetDirListing(std::string path) override { return std::vector(); } + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override { + if (exists) + *exists = true; + return std::vector(); + } int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override { return isoFileSystem_->OpenFile("", access, devicename); } diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 580c70e7f7..49ddcc892b 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -369,19 +369,17 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) } } -std::vector MetaFileSystem::GetDirListing(std::string path) -{ +std::vector MetaFileSystem::GetDirListing(const std::string &path, bool *exists) { std::lock_guard guard(lock); std::string of; IFileSystem *system; int error = MapFilePath(path, of, &system); - if (error == 0) - { - return system->GetDirListing(of); - } - else - { + if (error == 0) { + return system->GetDirListing(of, exists); + } else { std::vector empty; + if (exists) + *exists = false; return empty; } } diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 9a3b041c93..545f21bddc 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -103,7 +103,7 @@ public: std::string NormalizePrefix(std::string prefix) const; - std::vector GetDirListing(std::string path) override; + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override; int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override; void CloseFile(u32 handle) override; size_t ReadFile(u32 handle, u8 *pointer, s64 size) override; diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 9a9e0f8c8b..dbe130f30c 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -661,8 +661,7 @@ static void tmFromFiletime(tm &dest, FILETIME &src) } #endif -std::vector VirtualDiscFileSystem::GetDirListing(std::string path) -{ +std::vector VirtualDiscFileSystem::GetDirListing(const std::string &path, bool *exists) { std::vector myVector; // TODO(scoped): Switch this over to GetFilesInDir! @@ -681,9 +680,14 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) hFind = FindFirstFileEx(w32path.c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0); #endif if (hFind == INVALID_HANDLE_VALUE) { + if (exists) + *exists = false; return myVector; //the empty list } + if (exists) + *exists = true; + for (BOOL retval = 1; retval; retval = FindNextFile(hFind, &findData)) { if (!wcscmp(findData.cFileName, L"..") || !wcscmp(findData.cFileName, L".")) { continue; @@ -697,6 +701,7 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) } entry.access = 0555; + entry.exists = true; entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32); entry.name = ConvertWStringToUTF8(findData.cFileName); tmFromFiletime(entry.atime, findData.ftLastAccessTime); @@ -717,18 +722,24 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) DIR *dp = opendir(localPath.c_str()); #if HOST_IS_CASE_SENSITIVE - if(dp == NULL && FixPathCase(basePath, path, FPC_FILE_MUST_EXIST)) { + std::string fixedPath = path; + if(dp == NULL && FixPathCase(basePath, fixedPath, FPC_FILE_MUST_EXIST)) { // May have failed due to case sensitivity, try again - localPath = GetLocalPath(path); + localPath = GetLocalPath(fixedPath); dp = opendir(localPath.c_str()); } #endif if (dp == NULL) { ERROR_LOG(FILESYS,"Error opening directory %s\n", path.c_str()); + if (exists) + *exists = false; return myVector; } + if (exists) + *exists = true; + while ((dirp = readdir(dp)) != NULL) { if (!strcmp(dirp->d_name, "..") || !strcmp(dirp->d_name, ".")) { continue; @@ -736,13 +747,14 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) PSPFileInfo entry; struct stat s; - std::string fullName = (GetLocalPath(path) / std::string(dirp->d_name)).ToString(); + std::string fullName = (localPath / std::string(dirp->d_name)).ToString(); stat(fullName.c_str(), &s); if (S_ISDIR(s.st_mode)) entry.type = FILETYPE_DIRECTORY; else entry.type = FILETYPE_NORMAL; entry.access = 0555; + entry.exists = true; entry.name = dirp->d_name; entry.size = s.st_size; localtime_r((time_t*)&s.st_atime,&entry.atime); diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index 0c1b6db872..1af7b5d842 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -40,7 +40,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; PSPDevType DevType(u32 handle) override; - std::vector GetDirListing(std::string path) override; + std::vector GetDirListing(const std::string &path, bool *exists = nullptr) override; FileSystemFlags Flags() override { return FileSystemFlags::UMD; } u64 FreeSpace(const std::string &path) override { return 0; }