#include #include #include #include #include #include #include "DiabloUI/diabloui.h" #include "options.h" #include "storm/storm.h" #include "utils/file_util.h" #include "utils/log.hpp" #include "utils/paths.h" #include "utils/sdl_mutex.h" #include "utils/stubs.h" #include "utils/stdcompat/optional.hpp" // Include Windows headers for Get/SetLastError. #if defined(_WIN32) // Suppress definitions of `min` and `max` macros by : #define NOMINMAX 1 #define WIN32_LEAN_AND_MEAN #include #else // !defined(_WIN32) // On non-Windows, these are defined in 3rdParty/StormLib. extern "C" void SetLastError(std::uint32_t dwErrCode); extern "C" std::uint32_t GetLastError(); #endif namespace devilution { namespace { SdlMutex Mutex; } // namespace bool SFileReadFileThreadSafe(HANDLE hFile, void *buffer, size_t nNumberOfBytesToRead, size_t *read, int *lpDistanceToMoveHigh) { const std::lock_guard lock(Mutex); return SFileReadFile(hFile, buffer, nNumberOfBytesToRead, (unsigned int *)read, lpDistanceToMoveHigh); } bool SFileCloseFileThreadSafe(HANDLE hFile) { const std::lock_guard lock(Mutex); return SFileCloseFile(hFile); } bool SFileOpenFile(const char *filename, HANDLE *phFile) { bool result = false; if (!result && font_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)font_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && lang_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)lang_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && devilutionx_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)devilutionx_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (gbIsHellfire) { if (!result && hfvoice_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)hfvoice_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && hfmusic_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)hfmusic_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && hfbarb_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)hfbarb_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && hfbard_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)hfbard_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && hfmonk_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)hfmonk_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result) { result = SFileOpenFileEx((HANDLE)hellfire_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } } if (!result && spawn_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)spawn_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } if (!result && diabdat_mpq != nullptr) { result = SFileOpenFileEx((HANDLE)diabdat_mpq, filename, SFILE_OPEN_FROM_MPQ, phFile); } return result; } uint32_t SErrGetLastError() { return ::GetLastError(); } void SErrSetLastError(uint32_t dwErrCode) { ::SetLastError(dwErrCode); } #if defined(_WIN64) || defined(_WIN32) bool SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq) { const auto szMpqNameUtf16 = ToWideChar(szMpqName); if (szMpqNameUtf16 == nullptr) { LogError("UTF-8 -> UTF-16 conversion error code {}", ::GetLastError()); return false; } return SFileOpenArchive(szMpqNameUtf16.get(), dwPriority, dwFlags, phMpq); } #endif } // namespace devilution