mirror of
https://github.com/izzy2lost/ppsspp.git
synced 2026-03-10 12:43:04 -07:00
UI: Resolve symlinks when adding things to recent.
See #11131. This also normalizes paths, captialization, etc. as necessary.
This commit is contained in:
@@ -100,6 +100,28 @@ bool OpenCPPFile(std::fstream & stream, const std::string &filename, std::ios::o
|
||||
return stream.is_open();
|
||||
}
|
||||
|
||||
std::string ResolvePath(const std::string &path) {
|
||||
#ifdef _WIN32
|
||||
HANDLE hFile = CreateFile(ConvertUTF8ToWString(path).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return path;
|
||||
|
||||
wchar_t buf[1024] = {0};
|
||||
int result = GetFinalPathNameByHandle(hFile, buf, (int)ARRAY_SIZE(buf) - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
|
||||
if (result >= ARRAY_SIZE(buf))
|
||||
return path;
|
||||
|
||||
// Undo the \\?\C:\ syntax that's normally returned.
|
||||
if (buf[0] == '\\' && buf[1] == '\\' && buf[2] == '?' && buf[3] == '\\' && isalpha(buf[4]) && buf[5] == ':')
|
||||
return ConvertWStringToUTF8(buf).substr(4);
|
||||
return ConvertWStringToUTF8(buf);
|
||||
#else
|
||||
char buf[PATH_MAX + 1];
|
||||
if (realpath(path.c_str(), buf) == nullptr)
|
||||
return path;
|
||||
return buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remove any ending forward slashes from directory paths
|
||||
// Modifies argument.
|
||||
|
||||
@@ -58,6 +58,9 @@ struct FileDetails {
|
||||
FILE *OpenCFile(const std::string &filename, const char *mode);
|
||||
bool OpenCPPFile(std::fstream & stream, const std::string &filename, std::ios::openmode mode);
|
||||
|
||||
// Resolves symlinks and similar.
|
||||
std::string ResolvePath(const std::string &path);
|
||||
|
||||
// Returns true if file filename exists
|
||||
bool Exists(const std::string &filename);
|
||||
|
||||
|
||||
+18
-14
@@ -1209,28 +1209,32 @@ void Config::AddRecent(const std::string &file) {
|
||||
if (iMaxRecent <= 0)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string filename = ReplaceAll(file, "\\", "/");
|
||||
#else
|
||||
std::string filename = file;
|
||||
#endif
|
||||
|
||||
const std::string filename = File::ResolvePath(file);
|
||||
for (auto str = recentIsos.begin(); str != recentIsos.end(); ++str) {
|
||||
#ifdef _WIN32
|
||||
if (!strcmpIgnore((*str).c_str(), filename.c_str(), "\\", "/")) {
|
||||
#else
|
||||
if (!strcmp((*str).c_str(), filename.c_str())) {
|
||||
#endif
|
||||
const std::string recent = File::ResolvePath(*str);
|
||||
if (filename == recent) {
|
||||
recentIsos.erase(str);
|
||||
// We'll add it back below.
|
||||
}
|
||||
}
|
||||
|
||||
recentIsos.insert(recentIsos.begin(), filename);
|
||||
if ((int)recentIsos.size() > iMaxRecent)
|
||||
recentIsos.resize(iMaxRecent);
|
||||
}
|
||||
|
||||
void Config::RemoveRecent(const std::string &file) {
|
||||
// Don't bother with this if the user disabled recents (it's -1).
|
||||
if (iMaxRecent <= 0)
|
||||
return;
|
||||
|
||||
const std::string filename = File::ResolvePath(file);
|
||||
for (auto str = recentIsos.begin(); str != recentIsos.end(); ++str) {
|
||||
const std::string recent = File::ResolvePath(*str);
|
||||
if (filename == recent) {
|
||||
recentIsos.erase(str);
|
||||
}
|
||||
}
|
||||
recentIsos.insert(recentIsos.begin(), filename);
|
||||
if ((int)recentIsos.size() > iMaxRecent)
|
||||
recentIsos.resize(iMaxRecent);
|
||||
}
|
||||
|
||||
void Config::CleanRecent() {
|
||||
|
||||
@@ -428,6 +428,7 @@ public:
|
||||
|
||||
// Utility functions for "recent" management
|
||||
void AddRecent(const std::string &file);
|
||||
void RemoveRecent(const std::string &file);
|
||||
void CleanRecent();
|
||||
|
||||
static void DownloadCompletedCallback(http::Download &download);
|
||||
|
||||
@@ -44,7 +44,7 @@ VirtualDiscFileSystem::VirtualDiscFileSystem(IHandleAllocator *_hAlloc, std::str
|
||||
: basePath(_basePath),currentBlockIndex(0) {
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!endsWith(basePath, "\\"))
|
||||
if (!endsWith(basePath, "\\") && !endsWith(basePath, "/"))
|
||||
basePath = basePath + "\\";
|
||||
#else
|
||||
if (!endsWith(basePath, "/"))
|
||||
|
||||
@@ -66,10 +66,7 @@ bool GameInfo::Delete() {
|
||||
// Just delete the one file (TODO: handle two-disk games as well somehow).
|
||||
const char *fileToRemove = filePath_.c_str();
|
||||
File::Delete(fileToRemove);
|
||||
auto i = std::find(g_Config.recentIsos.begin(), g_Config.recentIsos.end(), fileToRemove);
|
||||
if (i != g_Config.recentIsos.end()) {
|
||||
g_Config.recentIsos.erase(i);
|
||||
}
|
||||
g_Config.RemoveRecent(filePath_);
|
||||
return true;
|
||||
}
|
||||
case IdentifiedFileType::PSP_PBP_DIRECTORY:
|
||||
|
||||
+4
-17
@@ -354,33 +354,20 @@ bool GameScreen::isRecentGame(const std::string &gamePath) {
|
||||
if (g_Config.iMaxRecent <= 0)
|
||||
return false;
|
||||
|
||||
const std::string resolved = File::ResolvePath(gamePath);
|
||||
for (auto it = g_Config.recentIsos.begin(); it != g_Config.recentIsos.end(); ++it) {
|
||||
#ifdef _WIN32
|
||||
if (!strcmpIgnore((*it).c_str(), gamePath.c_str(), "\\","/"))
|
||||
#else
|
||||
if (!strcmp((*it).c_str(), gamePath.c_str()))
|
||||
#endif
|
||||
const std::string recent = File::ResolvePath(*it);
|
||||
if (resolved == recent)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
UI::EventReturn GameScreen::OnRemoveFromRecent(UI::EventParams &e) {
|
||||
if (g_Config.iMaxRecent <= 0)
|
||||
return UI::EVENT_DONE;
|
||||
for (auto it = g_Config.recentIsos.begin(); it != g_Config.recentIsos.end(); ++it) {
|
||||
#ifdef _WIN32
|
||||
if (!strcmpIgnore((*it).c_str(), gamePath_.c_str(), "\\","/")) {
|
||||
#else
|
||||
if (!strcmp((*it).c_str(), gamePath_.c_str())) {
|
||||
#endif
|
||||
g_Config.recentIsos.erase(it);
|
||||
g_Config.RemoveRecent(gamePath_);
|
||||
screenManager()->switchScreen(new MainScreen());
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
class SetBackgroundPopupScreen : public PopupScreen {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user