// Returns true if file filename exists bool Exists(const std::string &filename) { // Make sure Windows will no longer handle critical errors, which means no annoying "No disk" dialog // Save the old error mode #if defined(_WIN32) && !defined(__MINGW32__) int OldMode = SetErrorMode(SEM_FAILCRITICALERRORS); #endif struct stat64 file_info; #if defined(_WIN32) && defined(UNICODE) && !defined(__MINGW32__) std::wstring copy = ConvertUTF8ToWString(filename); StripTailDirSlashes(copy); int result = _wstat64(copy.c_str(), &file_info); #else std::string copy(filename); StripTailDirSlashes(copy); int result = stat64(copy.c_str(), &file_info); #endif // Set the old error mode #if defined(_WIN32) && !defined(__MINGW32__) SetErrorMode(OldMode); #endif return (result == 0); }
// Returns true if successful, or path already exists. bool CreateDir(const std::string &path) { std::string fn = path; StripTailDirSlashes(fn); DEBUG_LOG(COMMON, "CreateDir('%s')", fn.c_str()); #ifdef _WIN32 if (::CreateDirectory(ConvertUTF8ToWString(fn).c_str(), NULL)) return true; DWORD error = GetLastError(); if (error == ERROR_ALREADY_EXISTS) { WARN_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: already exists", path.c_str()); return true; } ERROR_LOG(COMMON, "CreateDir: CreateDirectory failed on %s: %i", path.c_str(), error); return false; #else if (mkdir(fn.c_str(), 0755) == 0) return true; int err = errno; if (err == EEXIST) { WARN_LOG(COMMON, "CreateDir: mkdir failed on %s: already exists", fn.c_str()); return true; } ERROR_LOG(COMMON, "CreateDir: mkdir failed on %s: %s", fn.c_str(), strerror(err)); return false; #endif }
// Returns true if filename is a directory bool IsDirectory(const std::string &filename) { std::string fn = filename; StripTailDirSlashes(fn); #if defined(_WIN32) std::wstring copy = ConvertUTF8ToWString(fn); WIN32_FILE_ATTRIBUTE_DATA data{}; if (!GetFileAttributesEx(copy.c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { WARN_LOG(COMMON, "GetFileAttributes failed on %s: %08x", fn.c_str(), GetLastError()); return false; } DWORD result = data.dwFileAttributes; return (result & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; #else std::string copy(fn); struct stat file_info; int result = stat(copy.c_str(), &file_info); if (result < 0) { WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", fn.c_str(), GetLastErrorMsg()); return false; } return S_ISDIR(file_info.st_mode); #endif }
// Returns true if filename is a directory bool IsDirectory(const std::string &filename) { struct stat64 file_info; #if defined(_WIN32) && defined(UNICODE) && !defined(__MINGW32__) std::wstring copy = ConvertUTF8ToWString(filename); StripTailDirSlashes(copy); int result = _wstat64(copy.c_str(), &file_info); #else std::string copy(filename); StripTailDirSlashes(copy); int result = stat64(copy.c_str(), &file_info); #endif if (result < 0) { WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", filename.c_str(), GetLastErrorMsg()); return false; } return IsDirectory(file_info); }
// Returns true if file filename exists. Will return true on directories. bool Exists(const std::string &filename) { std::string fn = filename; StripTailDirSlashes(fn); #if defined(_WIN32) std::wstring copy = ConvertUTF8ToWString(fn); // Make sure Windows will no longer handle critical errors, which means no annoying "No disk" dialog int OldMode = SetErrorMode(SEM_FAILCRITICALERRORS); bool success = GetFileAttributes(copy.c_str()) != INVALID_FILE_ATTRIBUTES; SetErrorMode(OldMode); return success; #else struct stat64 file_info; return stat64(fn.c_str(), &file_info) == 0; #endif }
// Creates the full path of fullPath returns true on success bool CreateFullPath(const std::string &path) { std::string fullPath = path; StripTailDirSlashes(fullPath); int panicCounter = 100; VERBOSE_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); if (File::Exists(fullPath)) { DEBUG_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); return true; } size_t position = 0; #ifdef _WIN32 // Skip the drive letter, no need to create C:\. position = 3; #endif while (true) { // Find next sub path position = fullPath.find_first_of(DIR_SEP_CHRS, position); // we're done, yay! if (position == fullPath.npos) { if (!File::Exists(fullPath)) return File::CreateDir(fullPath); return true; } std::string subPath = fullPath.substr(0, position); if (position != 0 && !File::Exists(subPath)) File::CreateDir(subPath); // A safety check panicCounter--; if (panicCounter <= 0) { ERROR_LOG(COMMON, "CreateFullPath: directory structure too deep"); return false; } position++; } }
// Returns true if file filename exists. Will return true on directories. bool Exists(const std::string &filename) { std::string fn = filename; StripTailDirSlashes(fn); #if defined(_WIN32) std::wstring copy = ConvertUTF8ToWString(fn); // Make sure Windows will no longer handle critical errors, which means no annoying "No disk" dialog #if !PPSSPP_PLATFORM(UWP) int OldMode = SetErrorMode(SEM_FAILCRITICALERRORS); #endif WIN32_FILE_ATTRIBUTE_DATA data{}; if (!GetFileAttributesEx(copy.c_str(), GetFileExInfoStandard, &data) || data.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { return false; } #if !PPSSPP_PLATFORM(UWP) SetErrorMode(OldMode); #endif return true; #else struct stat file_info; return stat(fn.c_str(), &file_info) == 0; #endif }