mirror of https://github.com/PCSX2/pcsx2.git
FileSystem: Add OpenSharedCFile()
This commit is contained in:
parent
8c0120bdbb
commit
afa29facc6
|
@ -37,6 +37,7 @@
|
|||
#if defined(_WIN32)
|
||||
#include "RedtapeWindows.h"
|
||||
#include <winioctl.h>
|
||||
#include <share.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#if defined(_UWP)
|
||||
|
@ -595,12 +596,29 @@ std::string Path::Combine(const std::string_view& base, const std::string_view&
|
|||
}
|
||||
|
||||
#ifdef _UWP
|
||||
static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
||||
static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode, FileSystem::FileShareMode share_mode)
|
||||
{
|
||||
DWORD access = 0;
|
||||
DWORD share = 0;
|
||||
DWORD disposition = 0;
|
||||
|
||||
switch (share_mode)
|
||||
{
|
||||
case FileSystem::FileShareMode::DenyNone:
|
||||
share = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
break;
|
||||
case FileSystem::FileShareMode::DenyRead:
|
||||
share = FILE_SHARE_WRITE;
|
||||
break;
|
||||
case FileSystem::FileShareMode::DenyWrite:
|
||||
share = FILE_SHARE_READ;
|
||||
break;
|
||||
case FileSystem::FileShareMode::DenyReadWrite:
|
||||
default:
|
||||
share = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
const wchar_t* tmode = mode;
|
||||
while (*tmode)
|
||||
|
@ -608,7 +626,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
if (*tmode == L'r' && *(tmode + 1) == L'+')
|
||||
{
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = OPEN_EXISTING;
|
||||
flags |= _O_RDWR;
|
||||
tmode += 2;
|
||||
|
@ -616,7 +633,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
else if (*tmode == L'w' && *(tmode + 1) == L'+')
|
||||
{
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = CREATE_ALWAYS;
|
||||
flags |= _O_RDWR | _O_CREAT | _O_TRUNC;
|
||||
tmode += 2;
|
||||
|
@ -624,7 +640,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
else if (*tmode == L'a' && *(tmode + 1) == L'+')
|
||||
{
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = CREATE_ALWAYS;
|
||||
flags |= _O_RDWR | _O_APPEND | _O_CREAT | _O_TRUNC;
|
||||
tmode += 2;
|
||||
|
@ -632,7 +647,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
else if (*tmode == L'r')
|
||||
{
|
||||
access = GENERIC_READ;
|
||||
share = 0;
|
||||
disposition = OPEN_EXISTING;
|
||||
flags |= _O_RDONLY;
|
||||
tmode++;
|
||||
|
@ -640,7 +654,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
else if (*tmode == L'w')
|
||||
{
|
||||
access = GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = CREATE_ALWAYS;
|
||||
flags |= _O_WRONLY | _O_CREAT | _O_TRUNC;
|
||||
tmode++;
|
||||
|
@ -648,7 +661,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
else if (*tmode == L'a')
|
||||
{
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = CREATE_ALWAYS;
|
||||
flags |= _O_WRONLY | _O_APPEND | _O_CREAT | _O_TRUNC;
|
||||
tmode++;
|
||||
|
@ -670,7 +682,7 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
}
|
||||
else
|
||||
{
|
||||
Log_ErrorPrintf("Unknown mode flags: '%s'", StringUtil::WideStringToUTF8String(mode).c_str());
|
||||
Console.Error("Unknown mode flags: '%s'", StringUtil::WideStringToUTF8String(mode).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -681,7 +693,7 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
|||
|
||||
if (flags & _O_APPEND && !SetFilePointerEx(hFile, LARGE_INTEGER{}, nullptr, FILE_END))
|
||||
{
|
||||
Log_ErrorPrintf("SetFilePointerEx() failed: %08X", GetLastError());
|
||||
Console.Error("SetFilePointerEx() failed: %08X", GetLastError());
|
||||
CloseHandle(hFile);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -715,7 +727,7 @@ std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode)
|
|||
if (_wfopen_s(&fp, wfilename.c_str(), wmode.c_str()) != 0)
|
||||
{
|
||||
#ifdef _UWP
|
||||
return OpenCFileUWP(wfilename.c_str(), wmode.c_str());
|
||||
return OpenCFileUWP(wfilename.c_str(), wmode.c_str(), FileShareMode::DenyReadWrite);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
|
@ -755,6 +767,51 @@ FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFile(const char* filename, c
|
|||
return ManagedCFilePtr(OpenCFile(filename, mode), [](std::FILE* fp) { std::fclose(fp); });
|
||||
}
|
||||
|
||||
std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const std::wstring wfilename(StringUtil::UTF8StringToWideString(filename));
|
||||
const std::wstring wmode(StringUtil::UTF8StringToWideString(mode));
|
||||
if (wfilename.empty() || wmode.empty())
|
||||
return nullptr;
|
||||
|
||||
int share_flags = 0;
|
||||
switch (share_mode)
|
||||
{
|
||||
case FileShareMode::DenyNone:
|
||||
share_flags = _SH_DENYNO;
|
||||
break;
|
||||
case FileShareMode::DenyRead:
|
||||
share_flags = _SH_DENYRD;
|
||||
break;
|
||||
case FileShareMode::DenyWrite:
|
||||
share_flags = _SH_DENYWR;
|
||||
break;
|
||||
case FileShareMode::DenyReadWrite:
|
||||
default:
|
||||
share_flags = _SH_DENYRW;
|
||||
break;
|
||||
}
|
||||
|
||||
std::FILE* fp = _wfsopen(wfilename.c_str(), wmode.c_str(), share_flags);
|
||||
if (fp)
|
||||
return fp;
|
||||
|
||||
#ifdef _UWP
|
||||
return OpenCFileUWP(wfilename.c_str(), wmode.c_str(), share_mode);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
#else
|
||||
return std::fopen(filename, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
FileSystem::ManagedCFilePtr FileSystem::OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode)
|
||||
{
|
||||
return ManagedCFilePtr(OpenSharedCFile(filename, mode, share_mode), [](std::FILE* fp) { std::fclose(fp); });
|
||||
}
|
||||
|
||||
int FileSystem::FSeek64(std::FILE* fp, s64 offset, int whence)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -110,6 +110,20 @@ namespace FileSystem
|
|||
|
||||
int OpenFDFile(const char* filename, int flags, int mode);
|
||||
|
||||
/// Sharing modes for OpenSharedCFile().
|
||||
enum class FileShareMode
|
||||
{
|
||||
DenyReadWrite, /// Exclusive access.
|
||||
DenyWrite, /// Other processes can read from this file.
|
||||
DenyRead, /// Other processes can write to this file.
|
||||
DenyNone, /// Other processes can read and write to this file.
|
||||
};
|
||||
|
||||
/// Opens a file in shareable mode (where other processes can access it concurrently).
|
||||
/// Only has an effect on Windows systems.
|
||||
ManagedCFilePtr OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode);
|
||||
std::FILE* OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode);
|
||||
|
||||
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
|
||||
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
|
||||
std::optional<std::string> ReadFileToString(const char* filename);
|
||||
|
|
Loading…
Reference in New Issue