mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: [WIN32] Add a wrapper around GetProcAddress()
This commit is contained in:
parent
15f66329c2
commit
744a9e4745
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -956,10 +956,11 @@ float VideoDriver_Win32Base::GetDPIScale()
|
|||
static bool init_done = false;
|
||||
if (!init_done) {
|
||||
init_done = true;
|
||||
|
||||
_GetDpiForWindow = (PFNGETDPIFORWINDOW)GetProcAddress(GetModuleHandle(L"User32"), "GetDpiForWindow");
|
||||
_GetDpiForSystem = (PFNGETDPIFORSYSTEM)GetProcAddress(GetModuleHandle(L"User32"), "GetDpiForSystem");
|
||||
_GetDpiForMonitor = (PFNGETDPIFORMONITOR)GetProcAddress(LoadLibrary(L"Shcore.dll"), "GetDpiForMonitor");
|
||||
static DllLoader _user32(L"user32.dll");
|
||||
static DllLoader _shcore(L"shcore.dll");
|
||||
_GetDpiForWindow = _user32.GetProcAddress("GetDpiForWindow");
|
||||
_GetDpiForSystem = _user32.GetProcAddress("GetDpiForSystem");
|
||||
_GetDpiForMonitor = _shcore.GetProcAddress("GetDpiForMonitor");
|
||||
}
|
||||
|
||||
UINT cur_dpi = 0;
|
||||
|
|
Loading…
Reference in New Issue