mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-10 21:16:24 +02:00
Fix multiple issues preventing in-game saves from working.
This commit is contained in:
1 parent
2f04fc1c00
commit
e73e0dc0be
5 files changed
+83
-29
No files matched your search
@@ -155,32 +155,74 @@ FILE *OpenCFile(const Path &path, const char *mode) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::string OpenFlagToString(OpenFlag flags) {
|
||||
std::string s;
|
||||
if (flags & OPEN_READ)
|
||||
s += "READ|";
|
||||
if (flags & OPEN_WRITE)
|
||||
s += "WRITE|";
|
||||
if (flags & OPEN_APPEND)
|
||||
s += "APPEND|";
|
||||
if (flags & OPEN_CREATE)
|
||||
s += "CREATE|";
|
||||
if (flags & OPEN_TRUNCATE)
|
||||
s += "TRUNCATE|";
|
||||
if (!s.empty()) {
|
||||
s.pop_back(); // Remove trailing separator.
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int OpenFD(const Path &path, OpenFlag flags) {
|
||||
switch (path.Type()) {
|
||||
case PathType::CONTENT_URI:
|
||||
break;
|
||||
default:
|
||||
// Not yet supported.
|
||||
ERROR_LOG(COMMON, "OpenFD: Only supports Content URI paths. Not '%s' (%s)!", path.c_str(), OpenFlagToString(flags).c_str());
|
||||
// Not yet supported - use other paths.
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & OPEN_CREATE) {
|
||||
if (!File::Exists(path)) {
|
||||
INFO_LOG(COMMON, "OpenFD(%s): Creating file.", path.c_str());
|
||||
std::string name = path.GetFilename();
|
||||
if (path.CanNavigateUp()) {
|
||||
Path parent = path.NavigateUp();
|
||||
if (!Android_CreateFile(parent.ToString(), name)) {
|
||||
WARN_LOG(COMMON, "OpenFD: Failed to create file '%s' in '%s'", name.c_str(), parent.c_str());
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
INFO_LOG(COMMON, "Failed to navigate up to create file: %s", path.c_str());
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
INFO_LOG(COMMON, "OpenCFile(%s): Opening existing content file ('%s')", path.c_str(), OpenFlagToString(flags).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Android_OpenContentUriMode mode;
|
||||
if (flags == OPEN_READ) {
|
||||
mode = Android_OpenContentUriMode::READ;
|
||||
} else if (flags & OPEN_WRITE) {
|
||||
if (flags & OPEN_TRUNCATE) {
|
||||
mode = Android_OpenContentUriMode::READ_WRITE;
|
||||
} else {
|
||||
mode = Android_OpenContentUriMode::READ_WRITE_TRUNCATE;
|
||||
} else {
|
||||
mode = Android_OpenContentUriMode::READ_WRITE;
|
||||
}
|
||||
// TODO: Maybe better checking of additional flags here.
|
||||
} else {
|
||||
// TODO: Add support for more modes if possible.
|
||||
ERROR_LOG_REPORT_ONCE(openFlagNotSupported, COMMON, "OpenFlag 0x%x not yet supported", flags);
|
||||
ERROR_LOG_REPORT_ONCE(openFlagNotSupported, COMMON, "OpenFlag %s not yet supported", OpenFlagToString(flags).c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
INFO_LOG(COMMON, "Android_OpenContentUriFd: %s (%s)", path.c_str(), OpenFlagToString(flags).c_str());
|
||||
int descriptor = Android_OpenContentUriFd(path.ToString(), mode);
|
||||
if (descriptor < 0) {
|
||||
ERROR_LOG(COMMON, "Android_OpenContentUriFd failed: '%s'", path.c_str());
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -208,12 +208,12 @@ void SavedataParam::Init()
|
||||
pspFileSystem.MkDir(savePath);
|
||||
}
|
||||
// Create a nomedia file to hide save icons form Android image viewer
|
||||
#ifdef __ANDROID__
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
int handle = pspFileSystem.OpenFile(savePath + ".nomedia", (FileAccess)(FILEACCESS_CREATE | FILEACCESS_WRITE), 0);
|
||||
if (handle >= 0) {
|
||||
pspFileSystem.CloseFile(handle);
|
||||
} else {
|
||||
ERROR_LOG(IO, "Failed to create .nomedia file");
|
||||
INFO_LOG(IO, "Failed to create .nomedia file (might be ok if it already exists)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -67,8 +67,7 @@
|
||||
#endif
|
||||
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
static bool FixFilenameCase(const std::string &path, std::string &filename)
|
||||
{
|
||||
static bool FixFilenameCase(const std::string &path, std::string &filename) {
|
||||
// Are we lucky?
|
||||
if (File::Exists(Path(path + filename)))
|
||||
return true;
|
||||
@@ -112,8 +111,14 @@ static bool FixFilenameCase(const std::string &path, std::string &filename)
|
||||
return retValue;
|
||||
}
|
||||
|
||||
bool FixPathCase(const std::string &basePath, std::string &path, FixPathCaseBehavior behavior)
|
||||
{
|
||||
bool FixPathCase(const Path &realBasePath, std::string &path, FixPathCaseBehavior behavior) {
|
||||
if (realBasePath.Type() == PathType::CONTENT_URI) {
|
||||
// Nothing to do. These are already case insensitive, I think.
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string basePath = realBasePath.ToString();
|
||||
|
||||
size_t len = path.size();
|
||||
|
||||
if (len == 0)
|
||||
@@ -189,7 +194,7 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if (access & (FILEACCESS_APPEND | FILEACCESS_CREATE | FILEACCESS_WRITE)) {
|
||||
DEBUG_LOG(FILESYS, "Checking case for path %s", fileName.c_str());
|
||||
if (!FixPathCase(basePath.ToString(), fileName, FPC_PATH_MUST_EXIST)) {
|
||||
if (!FixPathCase(basePath, fileName, FPC_PATH_MUST_EXIST)) {
|
||||
error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;
|
||||
return false; // or go on and attempt (for a better error code than just 0?)
|
||||
}
|
||||
@@ -198,7 +203,7 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File
|
||||
#endif
|
||||
|
||||
Path fullName = GetLocalPath(basePath, fileName);
|
||||
VERBOSE_LOG(FILESYS, "Actually opening %s", fullName.c_str());
|
||||
INFO_LOG(FILESYS, "Actually opening %s", fullName.c_str());
|
||||
|
||||
// On the PSP, truncating doesn't lose data. If you seek later, you'll recover it.
|
||||
// This is abnormal, so we deviate from the PSP's behavior and truncate on write/close.
|
||||
@@ -289,6 +294,7 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File
|
||||
// Success
|
||||
return true;
|
||||
} else {
|
||||
ERROR_LOG(FILESYS, "File::OpenFD returned an error");
|
||||
// TODO: Need better error codes from OpenFD so we can distinguish
|
||||
// disk full. Just set not found for now.
|
||||
error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;
|
||||
@@ -296,6 +302,8 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File
|
||||
}
|
||||
}
|
||||
|
||||
INFO_LOG(FILESYS, "Opening '%s' straight", fullName.c_str());
|
||||
|
||||
int flags = 0;
|
||||
if (access & FILEACCESS_APPEND) {
|
||||
flags |= O_APPEND;
|
||||
@@ -320,7 +328,7 @@ bool DirectoryFileHandle::Open(const Path &basePath, std::string &fileName, File
|
||||
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if (!success && !(access & FILEACCESS_CREATE)) {
|
||||
if (!FixPathCase(basePath.ToString(), fileName, FPC_PATH_MUST_EXIST)) {
|
||||
if (!FixPathCase(basePath, fileName, FPC_PATH_MUST_EXIST)) {
|
||||
error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND;
|
||||
return false;
|
||||
}
|
||||
@@ -520,7 +528,7 @@ bool DirectoryFileSystem::MkDir(const std::string &dirname) {
|
||||
// duplicate (different case) directories
|
||||
|
||||
std::string fixedCase = dirname;
|
||||
if (!FixPathCase(basePath.ToString(), fixedCase, FPC_PARTIAL_ALLOWED))
|
||||
if (!FixPathCase(basePath, fixedCase, FPC_PARTIAL_ALLOWED))
|
||||
result = false;
|
||||
else
|
||||
result = File::CreateFullPath(GetLocalPath(fixedCase));
|
||||
@@ -540,7 +548,7 @@ bool DirectoryFileSystem::RmDir(const std::string &dirname) {
|
||||
|
||||
// Nope, fix case and try again. Should we try again?
|
||||
std::string fullPath = dirname;
|
||||
if (!FixPathCase(basePath.ToString(), fullPath, FPC_FILE_MUST_EXIST))
|
||||
if (!FixPathCase(basePath, fullPath, FPC_FILE_MUST_EXIST))
|
||||
return (bool)ReplayApplyDisk(ReplayAction::RMDIR, false, CoreTiming::GetGlobalTimeUs());
|
||||
|
||||
fullName = GetLocalPath(fullPath);
|
||||
@@ -571,7 +579,7 @@ int DirectoryFileSystem::RenameFile(const std::string &from, const std::string &
|
||||
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
// In case TO should overwrite a file with different case. Check error code?
|
||||
if (!FixPathCase(basePath.ToString(), fullTo, FPC_PATH_MUST_EXIST))
|
||||
if (!FixPathCase(basePath, fullTo, FPC_PATH_MUST_EXIST))
|
||||
return ReplayApplyDisk(ReplayAction::FILE_RENAME, -1, CoreTiming::GetGlobalTimeUs());
|
||||
#endif
|
||||
|
||||
@@ -584,7 +592,7 @@ int DirectoryFileSystem::RenameFile(const std::string &from, const std::string &
|
||||
{
|
||||
// May have failed due to case sensitivity on FROM, so try again. Check error code?
|
||||
std::string fullFromPath = from;
|
||||
if (!FixPathCase(basePath.ToString(), fullFromPath, FPC_FILE_MUST_EXIST))
|
||||
if (!FixPathCase(basePath, fullFromPath, FPC_FILE_MUST_EXIST))
|
||||
return ReplayApplyDisk(ReplayAction::FILE_RENAME, -1, CoreTiming::GetGlobalTimeUs());
|
||||
fullFrom = GetLocalPath(fullFromPath);
|
||||
|
||||
@@ -607,7 +615,7 @@ bool DirectoryFileSystem::RemoveFile(const std::string &filename) {
|
||||
{
|
||||
// May have failed due to case sensitivity, so try again. Try even if it fails?
|
||||
std::string fullNamePath = filename;
|
||||
if (!FixPathCase(basePath.ToString(), fullNamePath, FPC_FILE_MUST_EXIST))
|
||||
if (!FixPathCase(basePath, fullNamePath, FPC_FILE_MUST_EXIST))
|
||||
return (bool)ReplayApplyDisk(ReplayAction::FILE_REMOVE, false, CoreTiming::GetGlobalTimeUs());
|
||||
localPath = GetLocalPath(fullNamePath);
|
||||
|
||||
@@ -739,7 +747,7 @@ PSPFileInfo DirectoryFileSystem::GetFileInfo(std::string filename) {
|
||||
Path fullName = GetLocalPath(filename);
|
||||
if (!File::Exists(fullName)) {
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if (! FixPathCase(basePath.ToString(), filename, FPC_FILE_MUST_EXIST))
|
||||
if (! FixPathCase(basePath, filename, FPC_FILE_MUST_EXIST))
|
||||
return ReplayApplyDiskFileInfo(x, CoreTiming::GetGlobalTimeUs());
|
||||
fullName = GetLocalPath(filename);
|
||||
|
||||
@@ -852,13 +860,14 @@ std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
|
||||
std::vector<PSPFileInfo> myVector;
|
||||
|
||||
std::vector<File::FileInfo> files;
|
||||
if (!File::GetFilesInDir(GetLocalPath(path), &files, nullptr, 0)) {
|
||||
Path localPath = GetLocalPath(path);
|
||||
if (!File::GetFilesInDir(localPath, &files, nullptr, 0)) {
|
||||
// TODO: Case sensitivity should be checked on a file system basis, right?
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if (FixPathCase(basePath.ToString(), path, FPC_FILE_MUST_EXIST)) {
|
||||
if (FixPathCase(basePath, path, FPC_FILE_MUST_EXIST)) {
|
||||
// May have failed due to case sensitivity, try again
|
||||
localPath = GetLocalPath(path);
|
||||
if (!File::GetFilesInDir(GetLocalPath(path), &files, nullptr, 0)) {
|
||||
if (!File::GetFilesInDir(localPath, &files, nullptr, 0)) {
|
||||
return ReplayApplyDiskListing(myVector, CoreTiming::GetGlobalTimeUs());
|
||||
}
|
||||
}
|
||||
@@ -911,9 +920,9 @@ u64 DirectoryFileSystem::FreeSpace(const std::string &path) {
|
||||
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
std::string fixedCase = path;
|
||||
if (FixPathCase(basePath.ToString(), fixedCase, FPC_FILE_MUST_EXIST)) {
|
||||
if (FixPathCase(basePath, fixedCase, FPC_FILE_MUST_EXIST)) {
|
||||
// May have failed due to case sensitivity, try again.
|
||||
if (free_disk_space(GetLocalPath(fixedCase).ToString(), result)) {
|
||||
if (free_disk_space(GetLocalPath(fixedCase), result)) {
|
||||
return ReplayApplyDisk64(ReplayAction::FREESPACE, result, CoreTiming::GetGlobalTimeUs());
|
||||
}
|
||||
}
|
||||
@@ -1022,7 +1031,7 @@ int VFSFileSystem::OpenFile(std::string filename, FileAccess access, const char
|
||||
|
||||
std::string fullName = GetLocalPath(filename);
|
||||
const char *fullNameC = fullName.c_str();
|
||||
VERBOSE_LOG(FILESYS,"VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str());
|
||||
VERBOSE_LOG(FILESYS, "VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str());
|
||||
|
||||
size_t size;
|
||||
u8 *data = VFSReadFile(fullNameC, &size);
|
||||
|
||||
@@ -55,7 +55,7 @@ enum FixPathCaseBehavior {
|
||||
FPC_PARTIAL_ALLOWED, // don't care how many exist (mkdir recursive)
|
||||
};
|
||||
|
||||
bool FixPathCase(const std::string &basePath, std::string &path, FixPathCaseBehavior behavior);
|
||||
bool FixPathCase(const Path &basePath, std::string &path, FixPathCaseBehavior behavior);
|
||||
#endif
|
||||
|
||||
struct DirectoryFileHandle {
|
||||
|
||||
@@ -274,7 +274,7 @@ int VirtualDiscFileSystem::getFileListIndex(std::string &fileName)
|
||||
Path fullName = GetLocalPath(fileName);
|
||||
if (! File::Exists(fullName)) {
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if (! FixPathCase(basePath.ToString(), fileName, FPC_FILE_MUST_EXIST))
|
||||
if (! FixPathCase(basePath, fileName, FPC_FILE_MUST_EXIST))
|
||||
return -1;
|
||||
fullName = GetLocalPath(fileName);
|
||||
|
||||
@@ -602,7 +602,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) {
|
||||
Path fullName = GetLocalPath(filename);
|
||||
if (!File::Exists(fullName)) {
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if (! FixPathCase(basePath.ToString(), filename, FPC_FILE_MUST_EXIST))
|
||||
if (! FixPathCase(basePath, filename, FPC_FILE_MUST_EXIST))
|
||||
return x;
|
||||
fullName = GetLocalPath(filename);
|
||||
|
||||
@@ -661,6 +661,9 @@ static void tmFromFiletime(tm &dest, FILETIME &src)
|
||||
std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
|
||||
{
|
||||
std::vector<PSPFileInfo> myVector;
|
||||
|
||||
// TODO(scoped): Switch this over to GetFilesInDir!
|
||||
|
||||
#ifdef _WIN32
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE hFind;
|
||||
@@ -708,7 +711,7 @@ std::vector<PSPFileInfo> VirtualDiscFileSystem::GetDirListing(std::string path)
|
||||
DIR *dp = opendir(localPath.c_str());
|
||||
|
||||
#if HOST_IS_CASE_SENSITIVE
|
||||
if(dp == NULL && FixPathCase(basePath.ToString(), path, FPC_FILE_MUST_EXIST)) {
|
||||
if(dp == NULL && FixPathCase(basePath, path, FPC_FILE_MUST_EXIST)) {
|
||||
// May have failed due to case sensitivity, try again
|
||||
localPath = GetLocalPath(path);
|
||||
dp = opendir(localPath.c_str());
|
||||
|
||||
Reference in new issue
Block a user