From e8525a6f1461e64deb2668dda3bfbd40cdfd7b33 Mon Sep 17 00:00:00 2001 From: Sacha Date: Fri, 1 Aug 2014 04:20:00 +1000 Subject: [PATCH] More rFile cleanups and fixes. Was using fileExists/dirExists before when really should have just been exists. File or Dir doesn't matter and would only create false negatives. Current working directory shouldn't really be used at all. This is just the folder the application is run from (not even where the .exe resides). Some of the infos required by vfsLocalDir such as executable may not be portable. Not sure of their intended function as they are never used. --- Utilities/rFile.cpp | 210 ++++++++++++--------- Utilities/rFile.h | 32 ++-- rpcs3/Crypto/unpkg.cpp | 3 +- rpcs3/Crypto/unself.cpp | 5 +- rpcs3/Emu/FS/VFS.cpp | 3 +- rpcs3/Emu/FS/vfsDirBase.cpp | 2 +- rpcs3/Emu/FS/vfsLocalDir.cpp | 13 +- rpcs3/Emu/FS/vfsLocalFile.cpp | 6 +- rpcs3/Emu/GS/GL/GLGSRender.cpp | 6 +- rpcs3/Emu/GS/GL/GLGSRender.h | 4 +- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/sceNp.cpp | 15 +- rpcs3/Emu/System.cpp | 2 +- rpcs3/Gui/GameViewer.cpp | 2 +- rpcs3/Loader/PKG.cpp | 7 +- 15 files changed, 180 insertions(+), 132 deletions(-) diff --git a/Utilities/rFile.cpp b/Utilities/rFile.cpp index c0257fbed7..345aa284c5 100644 --- a/Utilities/rFile.cpp +++ b/Utilities/rFile.cpp @@ -15,6 +15,125 @@ std::wstring ConvertUTF8ToWString(const std::string &source) { } #endif +bool getFileInfo(const char *path, FileInfo *fileInfo) { + // TODO: Expand relative paths? + fileInfo->fullName = path; + +#ifdef _WIN32 + WIN32_FILE_ATTRIBUTE_DATA attrs; + if (!GetFileAttributesExW(ConvertUTF8ToWString(path).c_str(), GetFileExInfoStandard, &attrs)) { + fileInfo->size = 0; + fileInfo->isDirectory = false; + fileInfo->exists = false; + return false; + } + fileInfo->size = (uint64_t)attrs.nFileSizeLow | ((uint64_t)attrs.nFileSizeHigh << 32); + fileInfo->isDirectory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + fileInfo->isWritable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + fileInfo->exists = true; +#else + struct stat64 file_info; + int result = stat64(path, &file_info); + + if (result < 0) { + LOG_NOTICE(GENERAL, "IsDirectory: stat failed on %s", path); + fileInfo->exists = false; + return false; + } + + fileInfo->isDirectory = S_ISDIR(file_info.st_mode); + fileInfo->isWritable = false; + fileInfo->size = file_info.st_size; + fileInfo->exists = true; + // HACK: approximation + if (file_info.st_mode & 0200) + fileInfo->isWritable = true; +#endif + return true; +} + +bool rIsDir(const std::string &filename) { + FileInfo info; + getFileInfo(filename.c_str(), &info); + return info.isDirectory; +} + +bool rMkdir(const std::string &dir) +{ + return !mkdir(dir.c_str()); +} + +bool rMkpath(const std::string &path) +{ + size_t start=0, pos; + std::string dir; + bool ret; + + while (true) { + if ((pos = path.find_first_of('/', start)) == std::string::npos) + pos = path.length(); + + dir = path.substr(0,pos++); + start = pos; + if(dir.size() == 0) + continue; + if((ret = mkdir(dir.c_str())) && errno != EEXIST){ + return !ret; + } + if (pos == path.length()) + return true; + } + return true; +} + +bool rRmdir(const std::string &dir) +{ +#ifdef _WIN32 + if (!RemoveDirectory(ConvertUTF8ToWString(dir).c_str())) { + LOG_ERROR(GENERAL, "Error deleting directory %s: %i", dir.c_str(), GetLastError()); + return false; + } + return true; +#else + rmdir(dir.c_str()); +#endif +} + +bool rRename(const std::string &from, const std::string &to) +{ + // TODO: Deal with case-sensitivity +#ifdef _WIN32 + return (MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str()) == TRUE); +#else + return (0 == rename(from.c_str(), to.c_str())); +#endif +} + +bool rExists(const std::string &file) +{ +#ifdef _WIN32 + std::wstring wstr = ConvertUTF8ToWString(file); + return GetFileAttributes(wstr.c_str()) != 0xFFFFFFFF; +#else + struct stat buffer; + return (stat (file.c_str(), &buffer) == 0); +#endif +} + +bool rRemoveFile(const std::string &file) +{ +#ifdef _WIN32 + if (!DeleteFile(ConvertUTF8ToWString(file).c_str())) { + LOG_ERROR(GENERAL, "Error deleting %s: %i", file.c_str(), GetLastError()); + } +#else + int err = unlink(file.c_str()); + if (err) { + LOG_ERROR(GENERAL, "Error unlinking %s: %i", file.c_str(), err); + } +#endif +} + wxFile::OpenMode convertOpenMode(rFile::OpenMode open) { wxFile::OpenMode mode; @@ -143,7 +262,7 @@ bool rFile::Close() bool rFile::Create(const std::string &filename, bool overwrite, int access) { - return reinterpret_cast(handle)->Create(fmt::FromUTF8(filename),overwrite,access); + return reinterpret_cast(handle)->Create(fmt::FromUTF8(filename), overwrite, access); } bool rFile::Open(const std::string &filename, rFile::OpenMode mode, int access) @@ -151,11 +270,6 @@ bool rFile::Open(const std::string &filename, rFile::OpenMode mode, int access) return reinterpret_cast(handle)->Open(fmt::FromUTF8(filename), convertOpenMode(mode), access); } -bool rFile::Exists(const std::string &file) -{ - return rExists(file); -} - bool rFile::IsOpened() const { return reinterpret_cast(handle)->IsOpened(); @@ -181,85 +295,6 @@ size_t rFile::Tell() const return reinterpret_cast(handle)->Tell(); } -std::string rGetCwd() -{ - return fmt::ToUTF8(wxGetCwd()); -} - -bool rMkdir(const std::string &dir) -{ - return !mkdir(dir.c_str()); -} - -bool rMkpath(const std::string& path) -{ - return wxFileName::Mkdir(fmt::FromUTF8(path), 0777, wxPATH_MKDIR_FULL); -} - -bool rRmdir(const std::string &dir) -{ -#ifdef _WIN32 - if (!RemoveDirectory(ConvertUTF8ToWString(dir).c_str())) { - LOG_ERROR(GENERAL, "Error deleting directory %s: %i", dir, GetLastError()); - return false; - } - return true; -#else - rmdir(dir.c_str()); -#endif -} - -bool rRename(const std::string &from, const std::string &to) -{ - // TODO: Deal with case-sensitivity -#ifdef _WIN32 - return (MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str()) == TRUE); -#else - return (0 == rename(from.c_str(), to.c_str())); -#endif -} - -bool rExists(const std::string &file) -{ -#ifdef _WIN32 - std::wstring wstr = ConvertUTF8ToWString(file); - return GetFileAttributes(wstr.c_str()) != 0xFFFFFFFF; -#else - struct stat buffer; - return (stat (file.c_str(), &buffer) == 0); -#endif -} - -bool rDirExists(const std::string &path) -{ - return wxDirExists(fmt::FromUTF8(path)); -} - -bool rFileExists(const std::string &path) -{ - return wxFileExists(fmt::FromUTF8(path)); -} - -bool rRemoveFile(const std::string &path) -{ - return wxRemoveFile(fmt::FromUTF8(path)); -} - -bool rIsWritable(const std::string& path) -{ - return wxIsWritable(fmt::FromUTF8(path)); -} - -bool rIsReadable(const std::string& path) -{ - return wxIsReadable(fmt::FromUTF8(path)); -} - -bool rIsExecutable(const std::string& path) -{ - return wxIsExecutable(fmt::FromUTF8(path)); -} - rDir::rDir() { handle = reinterpret_cast(new wxDir()); @@ -280,11 +315,6 @@ bool rDir::Open(const std::string& path) return reinterpret_cast(handle)->Open(fmt::FromUTF8(path)); } -bool rDir::Exists(const std::string &path) -{ - return rFile::Exists(path); -} - bool rDir::GetFirst(std::string *filename) const { wxString str; diff --git a/Utilities/rFile.h b/Utilities/rFile.h index 55a760abef..fb2be71fbb 100644 --- a/Utilities/rFile.h +++ b/Utilities/rFile.h @@ -2,6 +2,24 @@ #include +struct FileInfo { + std::string name; + std::string fullName; + bool exists; + bool isDirectory; + bool isWritable; + uint64_t size; +}; + +bool getFileInfo(const char *path, FileInfo *fileInfo); +bool rIsDir(const std::string& filename); +bool rRmdir(const std::string& dir); +bool rMkdir(const std::string& dir); +bool rMkpath(const std::string& path); +bool rRename(const std::string &from, const std::string &to); +bool rExists(const std::string &path); +bool rRemoveFile(const std::string &path); + enum rSeekMode { rFromStart, @@ -41,20 +59,6 @@ public: void *handle; }; -std::string rGetCwd(); -bool rRmdir(const std::string& dir); -bool rMkdir(const std::string& dir); -bool rMkpath(const std::string& path); -bool rRename(const std::string &from, const std::string &to); -bool rExists(const std::string &path); -bool rDirExists(const std::string &path); -bool rFileExists(const std::string &path); -bool rRemoveFile(const std::string &path); - -bool rIsWritable(const std::string& path); -bool rIsReadable(const std::string& path); -bool rIsExecutable(const std::string& path); - struct rDir { rDir(); diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index 3d26e9178d..c08a3b5eab 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -191,7 +191,8 @@ int Unpack(rFile& pkg_f, std::string src, std::string dst) PKGHeader* m_header = (PKGHeader*) malloc (sizeof(PKGHeader)); rFile dec_pkg_f; - std::string decryptedFile = rGetCwd() + "/dev_hdd1/" + src + ".dec"; + // TODO: This shouldn't use current dir + std::string decryptedFile = "./dev_hdd1/" + src + ".dec"; dec_pkg_f.Create(decryptedFile, true); diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index eef46d2e28..d03091dae1 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -505,10 +505,11 @@ bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key) // Try to find a matching RAP file under dev_usb000. std::string ci_str((const char *)content_id); - std::string rap_path(rGetCwd() + "/dev_usb000/" + ci_str + ".rap"); + // TODO: This shouldn't use current dir + std::string rap_path("./dev_usb000/" + ci_str + ".rap"); // Check if we have a valid RAP file. - if (!rFile::Exists(rap_path)) + if (!rExists(rap_path)) { LOG_ERROR(LOADER, "This application requires a valid RAP file for decryption!"); return false; diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 3c79002e13..1776343ce8 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -291,7 +291,8 @@ void VFS::Init(const std::string& path) } std::string mpath = entry.path; - fmt::Replace(mpath,"$(EmulatorDir)", rGetCwd()); + // TODO: This shouldn't use current dir + fmt::Replace(mpath,"$(EmulatorDir)", "."); fmt::Replace(mpath,"$(GameDir)", vfsDevice::GetRoot(path)); Mount(entry.mount, mpath, dev); } diff --git a/rpcs3/Emu/FS/vfsDirBase.cpp b/rpcs3/Emu/FS/vfsDirBase.cpp index 63e5908dd0..14f4fdfc45 100644 --- a/rpcs3/Emu/FS/vfsDirBase.cpp +++ b/rpcs3/Emu/FS/vfsDirBase.cpp @@ -32,7 +32,7 @@ bool vfsDirBase::IsOpened() const bool vfsDirBase::IsExists(const std::string& path) const { - return rDirExists(path); + return rExists(path); } const std::vector& vfsDirBase::GetEntries() const diff --git a/rpcs3/Emu/FS/vfsLocalDir.cpp b/rpcs3/Emu/FS/vfsLocalDir.cpp index e97f9a5ad7..69008fa03b 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.cpp +++ b/rpcs3/Emu/FS/vfsLocalDir.cpp @@ -26,13 +26,18 @@ bool vfsLocalDir::Open(const std::string& path) std::string dir_path = path + name; m_entries.emplace_back(); + // TODO: Use same info structure as fileinfo? DirEntryInfo& info = m_entries.back(); info.name = name; - info.flags |= dir.Exists(dir_path) ? DirEntry_TypeDir : DirEntry_TypeFile; - if(rIsWritable(dir_path)) info.flags |= DirEntry_PermWritable; - if(rIsReadable(dir_path)) info.flags |= DirEntry_PermReadable; - if(rIsExecutable(dir_path)) info.flags |= DirEntry_PermExecutable; + FileInfo fileinfo; + getFileInfo(dir_path.c_str(), &fileinfo); + + // Not sure of purpose for below. I hope these don't need to be correct + info.flags |= rIsDir(dir_path) ? DirEntry_TypeDir : DirEntry_TypeFile; + if(fileinfo.isWritable) info.flags |= DirEntry_PermWritable; + info.flags |= DirEntry_PermReadable; // Always? + info.flags |= DirEntry_PermExecutable; // Always? } return true; diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index 7a6e71c09c..aea1e02e0c 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -63,7 +63,7 @@ bool vfsLocalFile::Create(const std::string& path) break; const std::string& dir = path.substr(0, p); - if(!rDirExists(dir)) + if(!rExists(dir)) { LOG_NOTICE(HLE, "create dir: %s", dir.c_str()); rMkdir(dir); @@ -72,7 +72,7 @@ bool vfsLocalFile::Create(const std::string& path) //create file const char m = path[path.length() - 1]; - if(m != '/' && m != '\\' && !rFileExists(path)) // ??? + if(m != '/' && m != '\\' && !rExists(path)) // ??? { rFile f; return f.Create(path); @@ -118,5 +118,5 @@ bool vfsLocalFile::IsOpened() const bool vfsLocalFile::Exists(const std::string& path) { - return rFileExists(path); + return rExists(path); } \ No newline at end of file diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 9126fba185..873a2167f1 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -359,7 +359,8 @@ bool GLGSRender::LoadProgram() m_shader_prog.Compile(); checkForGlError("m_shader_prog.Compile"); - rFile f(rGetCwd() + "/FragmentProgram.txt", rFile::write); + // TODO: This shouldn't use current dir + rFile f("./FragmentProgram.txt", rFile::write); f.Write(m_shader_prog.GetShaderText()); } @@ -372,7 +373,8 @@ bool GLGSRender::LoadProgram() m_vertex_prog.Compile(); checkForGlError("m_vertex_prog.Compile"); - rFile f(rGetCwd() + "/VertexProgram.txt", rFile::write); + // TODO: This shouldn't use current dir + rFile f("./VertexProgram.txt", rFile::write); f.Write(m_vertex_prog.shader); } diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 8596ed0116..325bca7fa4 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -593,10 +593,10 @@ public: static const std::string& dir_path = "textures"; static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; - if(!rDirExists(dir_path)) rMkdir(dir_path); + if(!rExists(dir_path)) rMkdir(dir_path); u32 count = 0; - while(rFileExists(fmt::Format(file_fmt, count))) count++; + while(rExists(fmt::Format(file_fmt, count))) count++; Save(tex, fmt::Format(file_fmt, count)); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index aae129c92a..703c6eb3c8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -660,7 +660,7 @@ int cellSysCacheClear(void) Emu.GetVFS().GetDevice(std::string("/dev_hdd1/cache/"), localPath); //TODO: implement - //if (rDirExists(localPath)){ + //if (rIsDir(localPath)){ // WxDirDeleteTraverser deleter; // wxString f = wxFindFirstFile(fmt::FromUTF8(localPath+"\\*"),wxDIR); // while (!f.empty()) diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index 6b5bce2a51..783adaaf48 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -53,10 +53,12 @@ int sceNpDrmIsAvailable(u32 k_licensee_addr, u32 drm_path_addr) //make more explicit what this actually does (currently everything after the third slash and before the fourth slash) std::string titleID = fmt::BeforeFirst(fmt::AfterFirst(fmt::AfterFirst(fmt::AfterFirst(drm_path,'/'),'/'),'/'),'/'); - std::string enc_drm_path = rGetCwd() + drm_path; - std::string dec_drm_path = rGetCwd() + "/dev_hdd1/" + titleID + "/" + drm_file_name; + // TODO: These shouldn't use current dir + std::string enc_drm_path = drm_path; + drm_path.insert(0, 1, '.'); + std::string dec_drm_path = "./dev_hdd1/" + titleID + "/" + drm_file_name; - std::string rap_dir_path = rGetCwd() + "/dev_usb000/"; + std::string rap_dir_path = "./dev_usb000/"; std::string rap_file_path = rap_dir_path; // Search dev_usb000 for a compatible RAP file. @@ -77,9 +79,10 @@ int sceNpDrmIsAvailable(u32 k_licensee_addr, u32 drm_path_addr) } // Create a new directory under dev_hdd1/titleID to hold the decrypted data. - std::string tmp_dir = rGetCwd() + "/dev_hdd1/" + titleID; - if (!rDir::Exists(tmp_dir)) - rMkdir(rGetCwd() + "/dev_hdd1/" + titleID); + // TODO: These shouldn't use current dir + std::string tmp_dir = "./dev_hdd1/" + titleID; + if (!rExists(tmp_dir)) + rMkdir("./dev_hdd1/" + titleID); // Decrypt this EDAT using the supplied k_licensee and matching RAP file. DecryptEDAT(enc_drm_path, dec_drm_path, 8, rap_file_path, k_licensee, false); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 0e66104969..554450d425 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -133,7 +133,7 @@ void Emulator::Load() { GetModuleManager().init(); - if(!rFileExists(m_path)) return; + if(!rExists(m_path)) return; if(IsSelf(m_path)) { diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 467389aeeb..f709031bb8 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -241,7 +241,7 @@ void GameViewer::RemoveGame(wxCommandEvent& event) Emu.GetVFS().UnMountAll(); - if (!rFile::Exists(localPath)) + if (!rExists(localPath)) return; //TODO: Replace wxWidgetsSpecific filesystem stuff? WxDirDeleteTraverser deleter; diff --git a/rpcs3/Loader/PKG.cpp b/rpcs3/Loader/PKG.cpp index 7c055c35be..c07e43a5fa 100644 --- a/rpcs3/Loader/PKG.cpp +++ b/rpcs3/Loader/PKG.cpp @@ -13,7 +13,8 @@ bool PKGLoader::Install(std::string dest) if (!pkg_f.IsOpened()) return false; - dest = rGetCwd() + dest; + // TODO: This shouldn't use current dir + dest.insert(0, 1, '.'); if (!dest.empty() && dest.back() != '/') dest += '/'; @@ -24,7 +25,7 @@ bool PKGLoader::Install(std::string dest) std::string titleID = std::string(title_id).substr(7, 9); - if (rDirExists(dest+titleID)) { + if (rExists(dest+titleID)) { rMessageDialog d_overwrite(NULL, "Another installation was found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO|rCENTRE); if (d_overwrite.ShowModal() != rID_YES) { LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str()); @@ -55,4 +56,4 @@ bool PKGLoader::Install(std::string dest) bool PKGLoader::Close() { return pkg_f.Close(); -} \ No newline at end of file +}