Common: Add UWP support for helper classes
This commit is contained in:
parent
281f7c5789
commit
03ab18909a
|
@ -20,10 +20,12 @@
|
|||
#endif
|
||||
|
||||
// require vista+
|
||||
#ifndef WINAPI_FAMILY
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
#include "windows_headers.h"
|
||||
#include <intrin.h>
|
||||
#include <tlhelp32.h>
|
||||
|
@ -13,7 +13,7 @@ static std::mutex s_AssertFailedMutex;
|
|||
|
||||
static inline void FreezeThreads(void** ppHandle)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
if (hSnapshot != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ static inline void FreezeThreads(void** ppHandle)
|
|||
|
||||
static inline void ResumeThreads(void* pHandle)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
HANDLE hSnapshot = (HANDLE)pHandle;
|
||||
if (pHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ void Y_OnAssertFailed(const char* szMessage, const char* szFunction, const char*
|
|||
char szMsg[512];
|
||||
std::snprintf(szMsg, sizeof(szMsg), "%s in function %s (%s:%u)", szMessage, szFunction, szFile, uLine);
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
||||
WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), szMsg, static_cast<DWORD>(std::strlen(szMsg)), NULL, NULL);
|
||||
OutputDebugStringA(szMsg);
|
||||
|
@ -114,7 +114,7 @@ void Y_OnPanicReached(const char* szMessage, const char* szFunction, const char*
|
|||
char szMsg[512];
|
||||
std::snprintf(szMsg, sizeof(szMsg), "%s in function %s (%s:%u)", szMessage, szFunction, szFile, uLine);
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
||||
WriteConsoleA(GetStdHandle(STD_ERROR_HANDLE), szMsg, static_cast<DWORD>(std::strlen(szMsg)), NULL, NULL);
|
||||
OutputDebugStringA(szMsg);
|
||||
|
|
|
@ -884,7 +884,7 @@ std::unique_ptr<ByteStream> ByteStream_OpenFileStream(const char* fileName, u32
|
|||
if ((openMode & (BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE)) == BYTESTREAM_OPEN_WRITE)
|
||||
{
|
||||
// if opening with write but not create, the path must exist.
|
||||
if (GetFileAttributes(fileName) == INVALID_FILE_ATTRIBUTES)
|
||||
if (!FileSystem::FileExists(fileName))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -895,7 +895,7 @@ std::unique_ptr<ByteStream> ByteStream_OpenFileStream(const char* fileName, u32
|
|||
{
|
||||
// if the file exists, use r+, otherwise w+
|
||||
// HACK: if we're not truncating, and the file exists (we want to only update it), we still have to use r+
|
||||
if ((openMode & BYTESTREAM_OPEN_TRUNCATE) || GetFileAttributes(fileName) == INVALID_FILE_ATTRIBUTES)
|
||||
if (!FileSystem::FileExists(fileName))
|
||||
{
|
||||
modeString[modeStringLength++] = 'w';
|
||||
if (openMode & BYTESTREAM_OPEN_READ)
|
||||
|
@ -1013,8 +1013,15 @@ std::unique_ptr<ByteStream> ByteStream_OpenFileStream(const char* fileName, u32
|
|||
DWORD desiredAccess = GENERIC_WRITE;
|
||||
if (openMode & BYTESTREAM_OPEN_READ)
|
||||
desiredAccess |= GENERIC_READ;
|
||||
|
||||
#ifndef _UWP
|
||||
HANDLE hFile =
|
||||
CreateFileW(wideTemporaryFileName.c_str(), desiredAccess, FILE_SHARE_DELETE, NULL, CREATE_NEW, 0, NULL);
|
||||
#else
|
||||
HANDLE hFile =
|
||||
CreateFile2FromAppW(wideTemporaryFileName.c_str(), desiredAccess, FILE_SHARE_DELETE, CREATE_NEW, nullptr);
|
||||
#endif
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return nullptr;
|
||||
|
||||
|
@ -1175,8 +1182,8 @@ std::unique_ptr<ByteStream> ByteStream_OpenFileStream(const char* fileName, u32
|
|||
}
|
||||
else // if (errno == ENOTDIR)
|
||||
{
|
||||
// well.. someone's trying to open a fucking weird path that is comprised of both directories and files...
|
||||
// I aint sticking around here to find out what disaster awaits... let fopen deal with it
|
||||
// well.. someone's trying to open a fucking weird path that is comprised of both directories and
|
||||
// files... I aint sticking around here to find out what disaster awaits... let fopen deal with it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
#include "windows_headers.h"
|
||||
|
||||
#include "thirdparty/StackWalker.h"
|
||||
|
|
|
@ -21,6 +21,20 @@
|
|||
|
||||
#if defined(_WIN32)
|
||||
#include <shlobj.h>
|
||||
|
||||
#if defined(_UWP)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Devices.Enumeration.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Storage.FileProperties.h>
|
||||
#include <winrt/Windows.Storage.Search.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
@ -713,7 +727,7 @@ std::vector<std::string> GetRootDirectoryList()
|
|||
{
|
||||
std::vector<std::string> results;
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
char buf[256];
|
||||
if (GetLogicalDriveStringsA(sizeof(buf), buf) != 0)
|
||||
{
|
||||
|
@ -725,6 +739,28 @@ std::vector<std::string> GetRootDirectoryList()
|
|||
ptr += len + 1u;
|
||||
}
|
||||
}
|
||||
#elif defined(_UWP)
|
||||
if (const auto install_location = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation();
|
||||
install_location)
|
||||
{
|
||||
if (const auto path = install_location.Path(); !path.empty())
|
||||
results.push_back(StringUtil::WideStringToUTF8String(path));
|
||||
}
|
||||
|
||||
if (const auto local_location = winrt::Windows::Storage::ApplicationData::Current().LocalFolder(); local_location)
|
||||
{
|
||||
if (const auto path = local_location.Path(); !path.empty())
|
||||
results.push_back(StringUtil::WideStringToUTF8String(path));
|
||||
}
|
||||
|
||||
const auto devices = winrt::Windows::Storage::KnownFolders::RemovableDevices();
|
||||
const auto folders_task(devices.GetFoldersAsync());
|
||||
for (const auto& storage_folder : folders_task.get())
|
||||
{
|
||||
const auto path = storage_folder.Path();
|
||||
if (!path.empty())
|
||||
results.push_back(StringUtil::WideStringToUTF8String(path));
|
||||
}
|
||||
#else
|
||||
const char* home_path = std::getenv("HOME");
|
||||
if (home_path)
|
||||
|
@ -772,6 +808,106 @@ FileSystem::ManagedCFilePtr OpenManagedCFile(const char* filename, const char* m
|
|||
return ManagedCFilePtr(OpenCFile(filename, mode), [](std::FILE* fp) { std::fclose(fp); });
|
||||
}
|
||||
|
||||
#ifdef _UWP
|
||||
std::FILE* OpenCFileUWP(const wchar_t* wfilename, const wchar_t* mode)
|
||||
{
|
||||
DWORD access = 0;
|
||||
DWORD share = 0;
|
||||
DWORD disposition = 0;
|
||||
|
||||
int flags = 0;
|
||||
const wchar_t* tmode = mode;
|
||||
while (*tmode)
|
||||
{
|
||||
if (*tmode == L'r' && *(tmode + 1) == L'+')
|
||||
{
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = OPEN_EXISTING;
|
||||
flags |= _O_RDWR;
|
||||
tmode += 2;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (*tmode == L'r')
|
||||
{
|
||||
access = GENERIC_READ;
|
||||
share = 0;
|
||||
disposition = OPEN_EXISTING;
|
||||
flags |= _O_RDONLY;
|
||||
tmode++;
|
||||
}
|
||||
else if (*tmode == L'w')
|
||||
{
|
||||
access = GENERIC_WRITE;
|
||||
share = 0;
|
||||
disposition = CREATE_ALWAYS;
|
||||
flags |= _O_WRONLY | _O_CREAT | _O_TRUNC;
|
||||
tmode++;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
else if (*tmode == L'b')
|
||||
{
|
||||
flags |= _O_BINARY;
|
||||
tmode++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log_ErrorPrintf("Unknown mode flags: '%s'", StringUtil::WideStringToUTF8String(mode).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE hFile = CreateFileFromAppW(wfilename, access, share, nullptr, disposition, 0, nullptr);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return nullptr;
|
||||
|
||||
if (flags & _O_APPEND && !SetFilePointerEx(hFile, LARGE_INTEGER{}, nullptr, FILE_END))
|
||||
{
|
||||
Log_ErrorPrintf("SetFilePointerEx() failed: %08X", GetLastError());
|
||||
CloseHandle(hFile);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int fd = _open_osfhandle(reinterpret_cast<intptr_t>(hFile), flags);
|
||||
if (fd < 0)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::FILE* fp = _wfdopen(fd, mode);
|
||||
if (!fp)
|
||||
{
|
||||
_close(fd);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
#endif // _UWP
|
||||
|
||||
std::FILE* OpenCFile(const char* filename, const char* mode)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -789,9 +925,16 @@ std::FILE* OpenCFile(const char* filename, const char* mode)
|
|||
{
|
||||
wfilename[wlen] = 0;
|
||||
wmode[wmodelen] = 0;
|
||||
|
||||
std::FILE* fp;
|
||||
if (_wfopen_s(&fp, wfilename, wmode) != 0)
|
||||
{
|
||||
#ifdef _UWP
|
||||
return OpenCFileUWP(wfilename, wmode);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
@ -1052,6 +1195,19 @@ static u32 TranslateWin32Attributes(u32 Win32Attributes)
|
|||
return r;
|
||||
}
|
||||
|
||||
static DWORD WrapGetFileAttributes(const wchar_t* path)
|
||||
{
|
||||
#ifndef _UWP
|
||||
return GetFileAttributesW(path);
|
||||
#else
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (!GetFileAttributesExFromAppW(path, GetFileExInfoStandard, &fad))
|
||||
return INVALID_FILE_ATTRIBUTES;
|
||||
|
||||
return fad.dwFileAttributes;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const u32 READ_DIRECTORY_CHANGES_NOTIFY_FILTER = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_CREATION;
|
||||
|
@ -1064,7 +1220,7 @@ public:
|
|||
m_directoryChangeQueued(false)
|
||||
{
|
||||
m_bufferSize = 16384;
|
||||
m_pBuffer = new byte[m_bufferSize];
|
||||
m_pBuffer = new u8[m_bufferSize];
|
||||
}
|
||||
|
||||
virtual ~ChangeNotifierWin32()
|
||||
|
@ -1103,7 +1259,7 @@ public:
|
|||
// has any bytes?
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
const byte* pCurrentPointer = m_pBuffer;
|
||||
const u8* pCurrentPointer = m_pBuffer;
|
||||
PathString fileName;
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1176,15 +1332,26 @@ private:
|
|||
HANDLE m_hDirectory;
|
||||
OVERLAPPED m_overlapped;
|
||||
bool m_directoryChangeQueued;
|
||||
byte* m_pBuffer;
|
||||
u8* m_pBuffer;
|
||||
u32 m_bufferSize;
|
||||
};
|
||||
|
||||
std::unique_ptr<ChangeNotifier> CreateChangeNotifier(const char* path, bool recursiveWatch)
|
||||
{
|
||||
// open the directory up
|
||||
HANDLE hDirectory = CreateFileA(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr);
|
||||
std::wstring path_wstr(StringUtil::UTF8StringToWideString(path));
|
||||
#ifndef _UWP
|
||||
HANDLE hDirectory =
|
||||
CreateFileW(path_wstr.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr,
|
||||
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr);
|
||||
#else
|
||||
CREATEFILE2_EXTENDED_PARAMETERS ep = {};
|
||||
ep.dwSize = sizeof(ep);
|
||||
ep.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||
ep.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;
|
||||
HANDLE hDirectory = CreateFile2FromAppW(path_wstr.c_str(), FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, OPEN_EXISTING, &ep);
|
||||
#endif
|
||||
if (hDirectory == nullptr)
|
||||
return nullptr;
|
||||
|
||||
|
@ -1212,8 +1379,18 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
|
|||
tempStr = StringUtil::StdStringFromFormat("%s\\*", OriginPath);
|
||||
}
|
||||
|
||||
// holder for utf-8 conversion
|
||||
WIN32_FIND_DATAW wfd;
|
||||
std::string utf8_filename;
|
||||
utf8_filename.reserve(countof(wfd.cFileName) * 2);
|
||||
|
||||
#ifndef _UWP
|
||||
HANDLE hFind = FindFirstFileW(StringUtil::UTF8StringToWideString(tempStr).c_str(), &wfd);
|
||||
#else
|
||||
HANDLE hFind = FindFirstFileExFromAppW(StringUtil::UTF8StringToWideString(tempStr).c_str(), FindExInfoBasic, &wfd,
|
||||
FindExSearchNameMatch, nullptr, 0);
|
||||
#endif
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
|
@ -1227,10 +1404,6 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
|
|||
wildCardMatchAll = !(std::strcmp(Pattern, "*"));
|
||||
}
|
||||
|
||||
// holder for utf-8 conversion
|
||||
std::string utf8_filename;
|
||||
utf8_filename.reserve(countof(wfd.cFileName) * 2);
|
||||
|
||||
// iterate results
|
||||
do
|
||||
{
|
||||
|
@ -1360,6 +1533,7 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* pStatData)
|
|||
|
||||
wpath[wlen] = 0;
|
||||
|
||||
#ifndef _UWP
|
||||
// determine attributes for the path. if it's a directory, things have to be handled differently..
|
||||
DWORD fileAttributes = GetFileAttributesW(wpath);
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
|
@ -1398,6 +1572,16 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* pStatData)
|
|||
pStatData->ModificationTime.SetWindowsFileTime(&bhfi.ftLastWriteTime);
|
||||
pStatData->Size = ((u64)bhfi.nFileSizeHigh) << 32 | (u64)bhfi.nFileSizeLow;
|
||||
return true;
|
||||
#else
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (!GetFileAttributesExFromAppW(wpath, GetFileExInfoStandard, &fad))
|
||||
return false;
|
||||
|
||||
pStatData->Attributes = TranslateWin32Attributes(fad.dwFileAttributes);
|
||||
pStatData->ModificationTime.SetWindowsFileTime(&fad.ftLastWriteTime);
|
||||
pStatData->Size = ((u64)fad.nFileSizeHigh) << 32 | (u64)fad.nFileSizeLow;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileSystem::StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData)
|
||||
|
@ -1447,7 +1631,7 @@ bool FileSystem::FileExists(const char* path)
|
|||
wpath[wlen] = 0;
|
||||
|
||||
// determine attributes for the path. if it's a directory, things have to be handled differently..
|
||||
DWORD fileAttributes = GetFileAttributesW(wpath);
|
||||
DWORD fileAttributes = WrapGetFileAttributes(wpath);
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
|
@ -1477,7 +1661,7 @@ bool FileSystem::DirectoryExists(const char* path)
|
|||
wpath[wlen] = 0;
|
||||
|
||||
// determine attributes for the path. if it's a directory, things have to be handled differently..
|
||||
DWORD fileAttributes = GetFileAttributesW(wpath);
|
||||
DWORD fileAttributes = WrapGetFileAttributes(wpath);
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
|
@ -1495,16 +1679,21 @@ bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
|||
if (wpath[0] == L'\0')
|
||||
return false;
|
||||
|
||||
// try just flat-out, might work if there's no other segments that have to be made
|
||||
// try just flat-out, might work if there's no other segments that have to be made
|
||||
#ifndef _UWP
|
||||
if (CreateDirectoryW(wpath.c_str(), nullptr))
|
||||
return true;
|
||||
#else
|
||||
if (CreateDirectoryFromAppW(wpath.c_str(), nullptr))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
// check error
|
||||
DWORD lastError = GetLastError();
|
||||
if (lastError == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
// check the attributes
|
||||
u32 Attributes = GetFileAttributesW(wpath.c_str());
|
||||
u32 Attributes = WrapGetFileAttributes(wpath.c_str());
|
||||
if (Attributes != INVALID_FILE_ATTRIBUTES && Attributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return true;
|
||||
else
|
||||
|
@ -1523,7 +1712,13 @@ bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
|||
if (wpath[i] == L'\\' || wpath[i] == L'/')
|
||||
{
|
||||
tempStr[i] = L'\0';
|
||||
if (!CreateDirectoryW(tempStr, nullptr))
|
||||
|
||||
#ifndef _UWP
|
||||
const BOOL result = CreateDirectoryW(tempStr, nullptr);
|
||||
#else
|
||||
const BOOL result = CreateDirectoryFromAppW(tempStr, nullptr);
|
||||
#endif
|
||||
if (!result)
|
||||
{
|
||||
lastError = GetLastError();
|
||||
if (lastError != ERROR_ALREADY_EXISTS) // fine, continue to next path segment
|
||||
|
@ -1537,7 +1732,12 @@ bool FileSystem::CreateDirectory(const char* Path, bool Recursive)
|
|||
// re-create the end if it's not a separator, check / as well because windows can interpret them
|
||||
if (wpath[pathLength - 1] != L'\\' && wpath[pathLength - 1] != L'/')
|
||||
{
|
||||
if (!CreateDirectoryW(wpath.c_str(), nullptr))
|
||||
#ifndef _UWP
|
||||
const BOOL result = CreateDirectoryW(wpath.c_str(), nullptr);
|
||||
#else
|
||||
const BOOL result = CreateDirectoryFromAppW(wpath.c_str(), nullptr);
|
||||
#endif
|
||||
if (!result)
|
||||
{
|
||||
lastError = GetLastError();
|
||||
if (lastError != ERROR_ALREADY_EXISTS)
|
||||
|
@ -1561,14 +1761,15 @@ bool FileSystem::DeleteFile(const char* Path)
|
|||
return false;
|
||||
|
||||
const std::wstring wpath(StringUtil::UTF8StringToWideString(Path));
|
||||
DWORD fileAttributes = GetFileAttributesW(wpath.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
const DWORD fileAttributes = WrapGetFileAttributes(wpath.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES || fileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return false;
|
||||
|
||||
if (!(fileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return (DeleteFileW(wpath.c_str()) == TRUE);
|
||||
else
|
||||
return false;
|
||||
#ifndef _UWP
|
||||
return (DeleteFileW(wpath.c_str()) == TRUE);
|
||||
#else
|
||||
return (DeleteFileFromAppW(wpath.c_str()) == TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileSystem::RenamePath(const char* OldPath, const char* NewPath)
|
||||
|
@ -1576,11 +1777,19 @@ bool FileSystem::RenamePath(const char* OldPath, const char* NewPath)
|
|||
const std::wstring old_wpath(StringUtil::UTF8StringToWideString(OldPath));
|
||||
const std::wstring new_wpath(StringUtil::UTF8StringToWideString(NewPath));
|
||||
|
||||
#ifndef _UWP
|
||||
if (!MoveFileExW(old_wpath.c_str(), new_wpath.c_str(), MOVEFILE_REPLACE_EXISTING))
|
||||
{
|
||||
Log_ErrorPrintf("MoveFileEx('%s', '%s') failed: %08X", OldPath, NewPath, GetLastError());
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (!ReplaceFileFromAppW(old_wpath.c_str(), new_wpath.c_str(), nullptr, 0, nullptr, nullptr))
|
||||
{
|
||||
Log_ErrorPrintf("MoveFileFromAppW('%s', '%s') failed: %08X", OldPath, NewPath, GetLastError());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1588,13 +1797,19 @@ bool FileSystem::RenamePath(const char* OldPath, const char* NewPath)
|
|||
static bool RecursiveDeleteDirectory(const std::wstring& wpath, bool Recursive)
|
||||
{
|
||||
// ensure it exists
|
||||
DWORD fileAttributes = GetFileAttributesW(wpath.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES || !(fileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
const DWORD fileAttributes = WrapGetFileAttributes(wpath.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES || fileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return false;
|
||||
|
||||
// non-recursive case just try removing the directory
|
||||
if (!Recursive)
|
||||
{
|
||||
#ifndef _UWP
|
||||
return (RemoveDirectoryW(wpath.c_str()) == TRUE);
|
||||
#else
|
||||
return (RemoveDirectoryFromAppW(wpath.c_str()) == TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// doing a recursive delete
|
||||
std::wstring fileName = wpath;
|
||||
|
@ -1602,7 +1817,12 @@ static bool RecursiveDeleteDirectory(const std::wstring& wpath, bool Recursive)
|
|||
|
||||
// is there any files?
|
||||
WIN32_FIND_DATAW findData;
|
||||
#ifndef _UWP
|
||||
HANDLE hFind = FindFirstFileW(fileName.c_str(), &findData);
|
||||
#else
|
||||
HANDLE hFind =
|
||||
FindFirstFileExFromAppW(fileName.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, 0);
|
||||
#endif
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
|
@ -1634,7 +1854,12 @@ static bool RecursiveDeleteDirectory(const std::wstring& wpath, bool Recursive)
|
|||
else
|
||||
{
|
||||
// found a file, so delete it
|
||||
if (!DeleteFileW(fileName.c_str()))
|
||||
#ifndef _UWP
|
||||
const BOOL result = DeleteFileW(fileName.c_str());
|
||||
#else
|
||||
const BOOL result = DeleteFileFromAppW(fileName.c_str());
|
||||
#endif
|
||||
if (!result)
|
||||
{
|
||||
FindClose(hFind);
|
||||
return false;
|
||||
|
@ -1644,7 +1869,12 @@ static bool RecursiveDeleteDirectory(const std::wstring& wpath, bool Recursive)
|
|||
FindClose(hFind);
|
||||
|
||||
// nuke the directory itself
|
||||
if (!RemoveDirectoryW(wpath.c_str()))
|
||||
#ifndef _UWP
|
||||
const BOOL result = RemoveDirectoryW(wpath.c_str());
|
||||
#else
|
||||
const BOOL result = RemoveDirectoryFromAppW(wpath.c_str());
|
||||
#endif
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
// done
|
||||
|
@ -1664,8 +1894,10 @@ std::string GetProgramPath()
|
|||
|
||||
// Fall back to the main module if this fails.
|
||||
HMODULE module = nullptr;
|
||||
#ifndef _UWP
|
||||
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCWSTR>(&GetProgramPath), &module);
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,21 @@ bool JitCodeBuffer::Allocate(u32 size /* = 64 * 1024 * 1024 */, u32 far_code_siz
|
|||
m_total_size = size + far_code_size;
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if !defined(_UWP)
|
||||
m_code_ptr = static_cast<u8*>(VirtualAlloc(nullptr, m_total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE));
|
||||
#else
|
||||
m_code_ptr = static_cast<u8*>(
|
||||
VirtualAlloc2FromApp(GetCurrentProcess(), nullptr, m_total_size, MEM_COMMIT, PAGE_READWRITE, nullptr, 0));
|
||||
if (m_code_ptr)
|
||||
{
|
||||
ULONG old_protection;
|
||||
if (!VirtualProtectFromApp(m_code_ptr, m_total_size, PAGE_EXECUTE_READWRITE, &old_protection))
|
||||
{
|
||||
VirtualFree(m_code_ptr, m_total_size, MEM_RELEASE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!m_code_ptr)
|
||||
{
|
||||
Log_ErrorPrintf("VirtualAlloc(RWX, %u) for internal buffer failed: %u", m_total_size, GetLastError());
|
||||
|
|
|
@ -9,6 +9,8 @@ public:
|
|||
JitCodeBuffer(void* buffer, u32 size, u32 far_code_size, u32 guard_size);
|
||||
~JitCodeBuffer();
|
||||
|
||||
bool IsValid() const { return (m_code_ptr != nullptr); }
|
||||
|
||||
bool Allocate(u32 size = 64 * 1024 * 1024, u32 far_code_size = 0);
|
||||
bool Initialize(void* buffer, u32 size, u32 far_code_size = 0, u32 guard_size = 0);
|
||||
void Destroy();
|
||||
|
|
|
@ -135,8 +135,13 @@ bool MemoryArena::Create(size_t size, bool writable, bool executable)
|
|||
|
||||
#if defined(_WIN32)
|
||||
const DWORD protect = (writable ? (executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE) : PAGE_READONLY);
|
||||
#ifndef _UWP
|
||||
m_file_handle = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, protect, Truncate32(size >> 32), Truncate32(size),
|
||||
file_mapping_name.c_str());
|
||||
#else
|
||||
m_file_handle = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, nullptr, protect, size,
|
||||
StringUtil::UTF8StringToWideString(file_mapping_name).c_str());
|
||||
#endif
|
||||
if (!m_file_handle)
|
||||
{
|
||||
Log_ErrorPrintf("CreateFileMapping failed: %u", GetLastError());
|
||||
|
@ -257,8 +262,16 @@ void* MemoryArena::CreateViewPtr(size_t offset, size_t size, bool writable, bool
|
|||
void* base_pointer;
|
||||
#if defined(_WIN32)
|
||||
const DWORD desired_access = FILE_MAP_READ | (writable ? FILE_MAP_WRITE : 0) | (executable ? FILE_MAP_EXECUTE : 0);
|
||||
#ifndef _UWP
|
||||
base_pointer =
|
||||
MapViewOfFileEx(m_file_handle, desired_access, Truncate32(offset >> 32), Truncate32(offset), size, fixed_address);
|
||||
#else
|
||||
// UWP does not support fixed mappings.
|
||||
if (!fixed_address)
|
||||
base_pointer = MapViewOfFileFromApp(m_file_handle, desired_access, offset, size);
|
||||
else
|
||||
base_pointer = nullptr;
|
||||
#endif
|
||||
if (!base_pointer)
|
||||
return nullptr;
|
||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||
|
|
|
@ -78,7 +78,7 @@ static bool IsStoreInstruction(const void* ptr)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && (defined(CPU_X64) || defined(CPU_AARCH64))
|
||||
#if defined(_WIN32) && !defined(_UWP) && (defined(CPU_X64) || defined(CPU_AARCH64))
|
||||
static PVOID s_veh_handle;
|
||||
|
||||
static LONG ExceptionHandler(PEXCEPTION_POINTERS exi)
|
||||
|
@ -110,6 +110,7 @@ static LONG ExceptionHandler(PEXCEPTION_POINTERS exi)
|
|||
}
|
||||
|
||||
s_in_handler = false;
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
@ -222,7 +223,7 @@ bool InstallHandler(void* owner, Callback callback)
|
|||
|
||||
if (was_empty)
|
||||
{
|
||||
#if defined(_WIN32) && (defined(CPU_X64) || defined(CPU_AARCH64))
|
||||
#if defined(_WIN32) && !defined(_UWP) && (defined(CPU_X64) || defined(CPU_AARCH64))
|
||||
s_veh_handle = AddVectoredExceptionHandler(1, ExceptionHandler);
|
||||
if (!s_veh_handle)
|
||||
{
|
||||
|
@ -279,7 +280,7 @@ bool RemoveHandler(void* owner)
|
|||
|
||||
if (m_handlers.empty())
|
||||
{
|
||||
#if defined(_WIN32) && (defined(CPU_X64) || defined(CPU_AARCH64))
|
||||
#if defined(_WIN32) && !defined(_UWP) && (defined(CPU_X64) || defined(CPU_AARCH64))
|
||||
RemoveVectoredExceptionHandler(s_veh_handle);
|
||||
s_veh_handle = nullptr;
|
||||
#elif defined(USE_SIGSEGV)
|
||||
|
|
|
@ -93,6 +93,7 @@ void Timer::SleepUntil(Value value, bool exact)
|
|||
if (diff <= 0)
|
||||
return;
|
||||
|
||||
#ifndef _UWP
|
||||
HANDLE timer = GetSleepTimer();
|
||||
if (timer)
|
||||
{
|
||||
|
@ -110,6 +111,7 @@ void Timer::SleepUntil(Value value, bool exact)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// falling back to sleep... bad.
|
||||
Sleep(static_cast<DWORD>(static_cast<std::uint64_t>(diff) / 1000000));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "common/log.h"
|
||||
Log_SetChannel(WindowInfo);
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(_WIN32) && !defined(_UWP)
|
||||
|
||||
#include "common/windows_headers.h"
|
||||
#include <dwmapi.h>
|
||||
|
|
|
@ -8,6 +8,7 @@ struct WindowInfo
|
|||
{
|
||||
Surfaceless,
|
||||
Win32,
|
||||
WinRT,
|
||||
X11,
|
||||
Wayland,
|
||||
MacOS,
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
#define NOMINMAX 1
|
||||
#endif
|
||||
|
||||
// require vista+
|
||||
// require vista+, but don't set it when compiling for UWP
|
||||
#ifndef WINAPI_FAMILY
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
|
Loading…
Reference in New Issue