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)
|
#if defined(_WIN32)
|
||||||
#include "RedtapeWindows.h"
|
#include "RedtapeWindows.h"
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
#include <share.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
|
||||||
#if defined(_UWP)
|
#if defined(_UWP)
|
||||||
|
@ -595,12 +596,29 @@ std::string Path::Combine(const std::string_view& base, const std::string_view&
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _UWP
|
#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 access = 0;
|
||||||
DWORD share = 0;
|
DWORD share = 0;
|
||||||
DWORD disposition = 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;
|
int flags = 0;
|
||||||
const wchar_t* tmode = mode;
|
const wchar_t* tmode = mode;
|
||||||
while (*tmode)
|
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'+')
|
if (*tmode == L'r' && *(tmode + 1) == L'+')
|
||||||
{
|
{
|
||||||
access = GENERIC_READ | GENERIC_WRITE;
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
share = 0;
|
|
||||||
disposition = OPEN_EXISTING;
|
disposition = OPEN_EXISTING;
|
||||||
flags |= _O_RDWR;
|
flags |= _O_RDWR;
|
||||||
tmode += 2;
|
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'+')
|
else if (*tmode == L'w' && *(tmode + 1) == L'+')
|
||||||
{
|
{
|
||||||
access = GENERIC_READ | GENERIC_WRITE;
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
share = 0;
|
|
||||||
disposition = CREATE_ALWAYS;
|
disposition = CREATE_ALWAYS;
|
||||||
flags |= _O_RDWR | _O_CREAT | _O_TRUNC;
|
flags |= _O_RDWR | _O_CREAT | _O_TRUNC;
|
||||||
tmode += 2;
|
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'+')
|
else if (*tmode == L'a' && *(tmode + 1) == L'+')
|
||||||
{
|
{
|
||||||
access = GENERIC_READ | GENERIC_WRITE;
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
share = 0;
|
|
||||||
disposition = CREATE_ALWAYS;
|
disposition = CREATE_ALWAYS;
|
||||||
flags |= _O_RDWR | _O_APPEND | _O_CREAT | _O_TRUNC;
|
flags |= _O_RDWR | _O_APPEND | _O_CREAT | _O_TRUNC;
|
||||||
tmode += 2;
|
tmode += 2;
|
||||||
|
@ -632,7 +647,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
||||||
else if (*tmode == L'r')
|
else if (*tmode == L'r')
|
||||||
{
|
{
|
||||||
access = GENERIC_READ;
|
access = GENERIC_READ;
|
||||||
share = 0;
|
|
||||||
disposition = OPEN_EXISTING;
|
disposition = OPEN_EXISTING;
|
||||||
flags |= _O_RDONLY;
|
flags |= _O_RDONLY;
|
||||||
tmode++;
|
tmode++;
|
||||||
|
@ -640,7 +654,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
||||||
else if (*tmode == L'w')
|
else if (*tmode == L'w')
|
||||||
{
|
{
|
||||||
access = GENERIC_WRITE;
|
access = GENERIC_WRITE;
|
||||||
share = 0;
|
|
||||||
disposition = CREATE_ALWAYS;
|
disposition = CREATE_ALWAYS;
|
||||||
flags |= _O_WRONLY | _O_CREAT | _O_TRUNC;
|
flags |= _O_WRONLY | _O_CREAT | _O_TRUNC;
|
||||||
tmode++;
|
tmode++;
|
||||||
|
@ -648,7 +661,6 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
||||||
else if (*tmode == L'a')
|
else if (*tmode == L'a')
|
||||||
{
|
{
|
||||||
access = GENERIC_READ | GENERIC_WRITE;
|
access = GENERIC_READ | GENERIC_WRITE;
|
||||||
share = 0;
|
|
||||||
disposition = CREATE_ALWAYS;
|
disposition = CREATE_ALWAYS;
|
||||||
flags |= _O_WRONLY | _O_APPEND | _O_CREAT | _O_TRUNC;
|
flags |= _O_WRONLY | _O_APPEND | _O_CREAT | _O_TRUNC;
|
||||||
tmode++;
|
tmode++;
|
||||||
|
@ -670,7 +682,7 @@ static std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
||||||
}
|
}
|
||||||
else
|
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;
|
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))
|
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);
|
CloseHandle(hFile);
|
||||||
return nullptr;
|
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)
|
if (_wfopen_s(&fp, wfilename.c_str(), wmode.c_str()) != 0)
|
||||||
{
|
{
|
||||||
#ifdef _UWP
|
#ifdef _UWP
|
||||||
return OpenCFileUWP(wfilename.c_str(), wmode.c_str());
|
return OpenCFileUWP(wfilename.c_str(), wmode.c_str(), FileShareMode::DenyReadWrite);
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
@ -755,6 +767,51 @@ FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFile(const char* filename, c
|
||||||
return ManagedCFilePtr(OpenCFile(filename, mode), [](std::FILE* fp) { std::fclose(fp); });
|
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)
|
int FileSystem::FSeek64(std::FILE* fp, s64 offset, int whence)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -110,6 +110,20 @@ namespace FileSystem
|
||||||
|
|
||||||
int OpenFDFile(const char* filename, int flags, int mode);
|
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(const char* filename);
|
||||||
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
|
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
|
||||||
std::optional<std::string> ReadFileToString(const char* filename);
|
std::optional<std::string> ReadFileToString(const char* filename);
|
||||||
|
|
Loading…
Reference in New Issue