From b0942cf40f2061719b4194476d648f7d872ecc14 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sun, 19 Feb 2017 10:04:54 +0100 Subject: [PATCH] Implement sceIoCreate flag O_EXCL. Should fix #9322 --- Core/FileSystems/DirectoryFileSystem.cpp | 18 +++++++++---- Core/FileSystems/FileSystem.h | 1 + Core/HLE/sceIo.cpp | 33 +++++++++++++----------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index b7639e9fcf..e6479ee8cb 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -174,10 +174,9 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil error = 0; #if HOST_IS_CASE_SENSITIVE - if (access & (FILEACCESS_APPEND|FILEACCESS_CREATE|FILEACCESS_WRITE)) - { + if (access & (FILEACCESS_APPEND|FILEACCESS_CREATE|FILEACCESS_WRITE)) { DEBUG_LOG(FILESYS, "Checking case for path %s", fileName.c_str()); - if ( ! FixPathCase(basePath, fileName, FPC_PATH_MUST_EXIST) ) + if (!FixPathCase(basePath, fileName, FPC_PATH_MUST_EXIST) ) return false; // or go on and attempt (for a better error code than just 0?) } // else we try fopen first (in case we're lucky) before simulating case insensitivity @@ -208,7 +207,11 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil sharemode |= FILE_SHARE_WRITE; } if (access & FILEACCESS_CREATE) { - openmode = OPEN_ALWAYS; + if (access & FILEACCESS_EXCL) { + openmode = CREATE_NEW; + } else { + openmode = OPEN_ALWAYS; + } } else { openmode = OPEN_EXISTING; } @@ -250,6 +253,9 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil if (access & FILEACCESS_CREATE) { flags |= O_CREAT; } + if (access & FILEACCESS_EXCL) { + flags |= O_EXCL; + } hFile = open(fullName.c_str(), flags, 0666); bool success = hFile != -1; @@ -257,7 +263,7 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil #if HOST_IS_CASE_SENSITIVE if (!success && !(access & FILEACCESS_CREATE)) { - if ( ! FixPathCase(basePath,fileName, FPC_PATH_MUST_EXIST) ) + if (!FixPathCase(basePath,fileName, FPC_PATH_MUST_EXIST) ) return 0; // or go on and attempt (for a better error code than just 0?) fullName = GetLocalPath(basePath,fileName); const char *fullNameC = fullName.c_str(); @@ -277,6 +283,8 @@ bool DirectoryFileHandle::Open(std::string &basePath, std::string &fileName, Fil #ifndef _WIN32 if (success) { + // Reject directories, even if we succeed in opening them. + // TODO: Might want to do this stat first... struct stat st; if (fstat(hFile, &st) == 0 && S_ISDIR(st.st_mode)) { close(hFile); diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 92aa5f04e8..a739f7197c 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -30,6 +30,7 @@ enum FileAccess { FILEACCESS_APPEND = 4, FILEACCESS_CREATE = 8, FILEACCESS_TRUNCATE = 16, + FILEACCESS_EXCL = 32, }; enum FileMove { diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index a73220102a..0c1e1ecbd6 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -87,15 +87,16 @@ umd00: block access - umd umd01: block access - umd */ -#define O_RDONLY 0x0001 -#define O_WRONLY 0x0002 -#define O_RDWR 0x0003 -#define O_NBLOCK 0x0010 -#define O_APPEND 0x0100 -#define O_CREAT 0x0200 -#define O_TRUNC 0x0400 -#define O_NOWAIT 0x8000 -#define O_NPDRM 0x40000000 +#define PSP_O_RDONLY 0x0001 +#define PSP_O_WRONLY 0x0002 +#define PSP_O_RDWR 0x0003 +#define PSP_O_NBLOCK 0x0010 +#define PSP_O_APPEND 0x0100 +#define PSP_O_CREAT 0x0200 +#define PSP_O_TRUNC 0x0400 +#define PSP_O_EXCL 0x0800 +#define PSP_O_NOWAIT 0x8000 +#define PSP_O_NPDRM 0x40000000 // chstat #define SCE_CST_MODE 0x0001 @@ -1326,16 +1327,18 @@ static u32 sceIoLseek32Async(int id, int offset, int whence) { static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) { //memory stick filename int access = FILEACCESS_NONE; - if (flags & O_RDONLY) + if (flags & PSP_O_RDONLY) access |= FILEACCESS_READ; - if (flags & O_WRONLY) + if (flags & PSP_O_WRONLY) access |= FILEACCESS_WRITE; - if (flags & O_APPEND) + if (flags & PSP_O_APPEND) access |= FILEACCESS_APPEND; - if (flags & O_CREAT) + if (flags & PSP_O_CREAT) access |= FILEACCESS_CREATE; - if (flags & O_TRUNC) + if (flags & PSP_O_TRUNC) access |= FILEACCESS_TRUNCATE; + if (flags & PSP_O_EXCL) + access |= FILEACCESS_EXCL; PSPFileInfo info = pspFileSystem.GetFileInfo(filename); @@ -1352,7 +1355,7 @@ static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) f->info = info; f->openMode = access; - f->npdrm = (flags & O_NPDRM)? true: false; + f->npdrm = (flags & PSP_O_NPDRM)? true: false; f->pgd_offset = 0; return f;