From 03ab18909a63c5ddf8b375767a8ca137f236cc83 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 4 Jul 2021 19:09:11 +1000 Subject: [PATCH] Common: Add UWP support for helper classes --- dep/vulkan-loader/include/vulkan_loader.h | 2 + src/common/assert.cpp | 10 +- src/common/byte_stream.cpp | 15 +- src/common/crash_handler.cpp | 2 +- src/common/file_system.cpp | 284 ++++++++++++++++++++-- src/common/jit_code_buffer.cpp | 14 ++ src/common/jit_code_buffer.h | 2 + src/common/memory_arena.cpp | 13 + src/common/page_fault_handler.cpp | 7 +- src/common/timer.cpp | 2 + src/common/window_info.cpp | 2 +- src/common/window_info.h | 1 + src/common/windows_headers.h | 4 +- 13 files changed, 317 insertions(+), 41 deletions(-) diff --git a/dep/vulkan-loader/include/vulkan_loader.h b/dep/vulkan-loader/include/vulkan_loader.h index bf6eb17b4..b2b3fc9ef 100644 --- a/dep/vulkan-loader/include/vulkan_loader.h +++ b/dep/vulkan-loader/include/vulkan_loader.h @@ -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 diff --git a/src/common/assert.cpp b/src/common/assert.cpp index 03ce57d41..6d83991dc 100644 --- a/src/common/assert.cpp +++ b/src/common/assert.cpp @@ -3,7 +3,7 @@ #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UWP) #include "windows_headers.h" #include #include @@ -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(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(std::strlen(szMsg)), NULL, NULL); OutputDebugStringA(szMsg); diff --git a/src/common/byte_stream.cpp b/src/common/byte_stream.cpp index 53ba73242..1ae2d82b7 100644 --- a/src/common/byte_stream.cpp +++ b/src/common/byte_stream.cpp @@ -884,7 +884,7 @@ std::unique_ptr 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_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_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_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; } } diff --git a/src/common/crash_handler.cpp b/src/common/crash_handler.cpp index 1db770de6..33c74b022 100644 --- a/src/common/crash_handler.cpp +++ b/src/common/crash_handler.cpp @@ -4,7 +4,7 @@ #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UWP) #include "windows_headers.h" #include "thirdparty/StackWalker.h" diff --git a/src/common/file_system.cpp b/src/common/file_system.cpp index 2602fef97..408d0b605 100644 --- a/src/common/file_system.cpp +++ b/src/common/file_system.cpp @@ -21,6 +21,20 @@ #if defined(_WIN32) #include + +#if defined(_UWP) +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#endif + #else #include #include @@ -713,7 +727,7 @@ std::vector GetRootDirectoryList() { std::vector results; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UWP) char buf[256]; if (GetLogicalDriveStringsA(sizeof(buf), buf) != 0) { @@ -725,6 +739,28 @@ std::vector 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(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 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(&GetProgramPath), &module); +#endif for (;;) { diff --git a/src/common/jit_code_buffer.cpp b/src/common/jit_code_buffer.cpp index ee595833c..d59d47078 100644 --- a/src/common/jit_code_buffer.cpp +++ b/src/common/jit_code_buffer.cpp @@ -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(VirtualAlloc(nullptr, m_total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE)); +#else + m_code_ptr = static_cast( + 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()); diff --git a/src/common/jit_code_buffer.h b/src/common/jit_code_buffer.h index 3c6b210ef..e4a3f4185 100644 --- a/src/common/jit_code_buffer.h +++ b/src/common/jit_code_buffer.h @@ -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(); diff --git a/src/common/memory_arena.cpp b/src/common/memory_arena.cpp index d89f388dc..02d7b68f6 100644 --- a/src/common/memory_arena.cpp +++ b/src/common/memory_arena.cpp @@ -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__) diff --git a/src/common/page_fault_handler.cpp b/src/common/page_fault_handler.cpp index 9be882561..fce40fea7 100644 --- a/src/common/page_fault_handler.cpp +++ b/src/common/page_fault_handler.cpp @@ -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) diff --git a/src/common/timer.cpp b/src/common/timer.cpp index 22a3a10d0..79b49684d 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp @@ -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(static_cast(diff) / 1000000)); diff --git a/src/common/window_info.cpp b/src/common/window_info.cpp index 65c8a51b7..ca2b2f901 100644 --- a/src/common/window_info.cpp +++ b/src/common/window_info.cpp @@ -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 diff --git a/src/common/window_info.h b/src/common/window_info.h index 626d54753..be1cc15b4 100644 --- a/src/common/window_info.h +++ b/src/common/window_info.h @@ -8,6 +8,7 @@ struct WindowInfo { Surfaceless, Win32, + WinRT, X11, Wayland, MacOS, diff --git a/src/common/windows_headers.h b/src/common/windows_headers.h index 9d882c640..0e242a789 100644 --- a/src/common/windows_headers.h +++ b/src/common/windows_headers.h @@ -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