summaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
authorglx22 <glx@openttd.org>2021-05-14 15:26:03 +0200
committerLoïc Guilloux <glx22@users.noreply.github.com>2021-06-10 23:17:29 +0200
commit744a9e474575af90935807620bff860c02559d76 (patch)
tree1c9dc114fb609d12cc9faffd16e88f177696dd13 /src/os
parent15f66329c28cb0aa3107dbb8da71281b1501be6b (diff)
downloadopenttd-744a9e474575af90935807620bff860c02559d76.tar.xz
Codechange: [WIN32] Add a wrapper around GetProcAddress()
Diffstat (limited to 'src/os')
-rw-r--r--src/os/windows/crashlog_win.cpp38
-rw-r--r--src/os/windows/font_win32.cpp3
-rw-r--r--src/os/windows/win32.cpp27
-rw-r--r--src/os/windows/win32.h43
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);