diff options
Diffstat (limited to 'src/os/windows')
-rw-r--r-- | src/os/windows/crashlog_win.cpp | 38 | ||||
-rw-r--r-- | src/os/windows/font_win32.cpp | 3 | ||||
-rw-r--r-- | src/os/windows/win32.cpp | 27 | ||||
-rw-r--r-- | src/os/windows/win32.h | 43 |
4 files changed, 61 insertions, 50 deletions
diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 1d3ed5193..5ce04e52e 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -368,22 +368,7 @@ static const uint MAX_FRAMES = 64; char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) const { -#define M(x) x "\0" - static const char dbg_import[] = - M("dbghelp.dll") - M("SymInitialize") - M("SymSetOptions") - M("SymCleanup") - M("StackWalk64") - M("SymFunctionTableAccess64") - M("SymGetModuleBase64") - M("SymGetModuleInfo64") - M("SymGetSymFromAddr64") - M("SymGetLineFromAddr64") - M("") - ; -#undef M - + DllLoader dbghelp(L"dbghelp.dll"); struct ProcPtrs { BOOL (WINAPI * pSymInitialize)(HANDLE, PCSTR, BOOL); BOOL (WINAPI * pSymSetOptions)(DWORD); @@ -394,12 +379,22 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c BOOL (WINAPI * pSymGetModuleInfo64)(HANDLE, DWORD64, PIMAGEHLP_MODULE64); BOOL (WINAPI * pSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64); BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64); - } proc; + } proc = { + dbghelp.GetProcAddress("SymInitialize"), + dbghelp.GetProcAddress("SymSetOptions"), + dbghelp.GetProcAddress("SymCleanup"), + dbghelp.GetProcAddress("StackWalk64"), + dbghelp.GetProcAddress("SymFunctionTableAccess64"), + dbghelp.GetProcAddress("SymGetModuleBase64"), + dbghelp.GetProcAddress("SymGetModuleInfo64"), + dbghelp.GetProcAddress("SymGetSymFromAddr64"), + dbghelp.GetProcAddress("SymGetLineFromAddr64"), + }; buffer += seprintf(buffer, last, "\nDecoded stack trace:\n"); /* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */ - if (LoadLibraryList((Function*)&proc, dbg_import)) { + if (dbghelp.Success()) { /* Initialize symbol handler. */ HANDLE hCur = GetCurrentProcess(); proc.pSymInitialize(hCur, nullptr, TRUE); @@ -486,14 +481,14 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c /* virtual */ int CrashLogWindows::WriteCrashDump(char *filename, const char *filename_last) const { int ret = 0; - HMODULE dbghelp = LoadLibrary(L"dbghelp.dll"); - if (dbghelp != nullptr) { + DllLoader dbghelp(L"dbghelp.dll"); + if (dbghelp.Success()) { typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, CONST PMINIDUMP_EXCEPTION_INFORMATION, CONST PMINIDUMP_USER_STREAM_INFORMATION, CONST PMINIDUMP_CALLBACK_INFORMATION); - MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump"); + MiniDumpWriteDump_t funcMiniDumpWriteDump = dbghelp.GetProcAddress("MiniDumpWriteDump"); if (funcMiniDumpWriteDump != nullptr) { seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str()); HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0); @@ -519,7 +514,6 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c } else { ret = -1; } - FreeLibrary(dbghelp); } return ret; } diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index 6c4e67deb..956e4a85c 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -620,8 +620,9 @@ void LoadWin32Font(FontSize fs) if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) { /* Try a nice little undocumented function first for getting the internal font name. * Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */ + static DllLoader _gdi32(L"gdi32.dll"); typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD); - static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(L"Gdi32"), "GetFontResourceInfoW"); + static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetProcAddress("GetFontResourceInfoW"); if (GetFontResourceInfo != nullptr) { /* Try to query an array of LOGFONTs that describe the file. */ diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 4478caa65..788021008 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.cpp @@ -50,30 +50,6 @@ bool MyShowCursor(bool show, bool toggle) return !show; } -/** - * Helper function needed by dynamically loading libraries - */ -bool LoadLibraryList(Function proc[], const char *dll) -{ - while (*dll != '\0') { - HMODULE lib; - lib = LoadLibrary(OTTD2FS(dll).c_str()); - - if (lib == nullptr) return false; - for (;;) { - FARPROC p; - - while (*dll++ != '\0') { /* Nothing */ } - if (*dll == '\0') break; - p = GetProcAddress(lib, dll); - if (p == nullptr) return false; - *proc++ = (Function)p; - } - dll++; - } - return true; -} - void ShowOSErrorBox(const char *buf, bool system) { MyShowCursor(true); @@ -679,7 +655,8 @@ int OTTDStringCompare(const char *s1, const char *s2) #endif if (first_time) { - _CompareStringEx = (PFNCOMPARESTRINGEX)GetProcAddress(GetModuleHandle(L"Kernel32"), "CompareStringEx"); + static DllLoader _kernel32(L"Kernel32.dll"); + _CompareStringEx = _kernel32.GetProcAddress("CompareStringEx"); first_time = false; } diff --git a/src/os/windows/win32.h b/src/os/windows/win32.h index bf88e312a..1d3127330 100644 --- a/src/os/windows/win32.h +++ b/src/os/windows/win32.h @@ -13,8 +13,47 @@ #include <windows.h> bool MyShowCursor(bool show, bool toggle = false); -typedef void (*Function)(int); -bool LoadLibraryList(Function proc[], const char *dll); +class DllLoader { +public: + explicit DllLoader(LPCTSTR filename) + { + this->hmodule = ::LoadLibrary(filename); + if (this->hmodule == nullptr) this->success = false; + } + + + ~DllLoader() + { + ::FreeLibrary(this->hmodule); + } + + bool Success() { return this->success; } + + class ProcAddress { + public: + explicit ProcAddress(void *p) : p(p) {} + + template <typename T, typename = std::enable_if_t<std::is_function_v<T>>> + operator T *() const + { + return reinterpret_cast<T *>(this->p); + } + + private: + void *p; + }; + + ProcAddress GetProcAddress(const char *proc_name) + { + void *p = reinterpret_cast<void *>(::GetProcAddress(this->hmodule, proc_name)); + if (p == nullptr) this->success = false; + return ProcAddress(p); + } + +private: + HMODULE hmodule = nullptr; + bool success = true; +}; char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen); wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen); |