Win32: simplify loading of DLL functions

Dynamic loading of DLL functions is duplicated in several places.

Add a set of macros to simplify the process.

Signed-off-by: Karsten Blees <blees@dcon.de>
This commit is contained in:
Karsten Blees
2014-08-25 21:58:44 +02:00
committed by Johannes Schindelin
parent 6e0213549e
commit d1ffd7909c
3 changed files with 53 additions and 33 deletions

View File

@@ -2017,23 +2017,16 @@ static const char *make_backslash_path(const char *path)
void mingw_open_html(const char *unixpath)
{
const char *htmlpath = make_backslash_path(unixpath);
typedef HINSTANCE (WINAPI *T)(HWND, const char *,
const char *, const char *, const char *, INT);
T ShellExecute;
HMODULE shell32;
int r;
DECLARE_PROC_ADDR(shell32.dll, HINSTANCE, ShellExecuteA,
HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT);
shell32 = LoadLibrary("shell32.dll");
if (!shell32)
if (!INIT_PROC_ADDR(ShellExecuteA))
die("cannot load shell32.dll");
ShellExecute = (T)GetProcAddress(shell32, "ShellExecuteA");
if (!ShellExecute)
die("cannot run browser");
printf("Launching default browser to display HTML ...\n");
r = HCAST(int, ShellExecute(NULL, "open", htmlpath,
r = HCAST(int, ShellExecuteA(NULL, "open", htmlpath,
NULL, "\\", SW_SHOWNORMAL));
FreeLibrary(shell32);
/* see the MSDN documentation referring to the result codes here */
if (r <= 32) {
die("failed to launch browser for %.*s", MAX_PATH, unixpath);
@@ -2042,24 +2035,18 @@ void mingw_open_html(const char *unixpath)
int link(const char *oldpath, const char *newpath)
{
typedef BOOL (WINAPI *T)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
static T create_hard_link = NULL;
DECLARE_PROC_ADDR(kernel32.dll, BOOL, CreateHardLinkW,
LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
wchar_t woldpath[MAX_LONG_PATH], wnewpath[MAX_LONG_PATH];
if (!INIT_PROC_ADDR(CreateHardLinkW))
return -1;
if (xutftowcs_long_path(woldpath, oldpath) < 0 ||
xutftowcs_long_path(wnewpath, newpath) < 0)
return -1;
if (!create_hard_link) {
create_hard_link = (T) GetProcAddress(
GetModuleHandle("kernel32.dll"), "CreateHardLinkW");
if (!create_hard_link)
create_hard_link = (T)-1;
}
if (create_hard_link == (T)-1) {
errno = ENOSYS;
return -1;
}
if (!create_hard_link(wnewpath, woldpath, NULL)) {
if (!CreateHardLinkW(wnewpath, woldpath, NULL)) {
errno = err_win_to_posix(GetLastError());
return -1;
}

View File

@@ -40,4 +40,41 @@ static inline int get_file_attr(const char *fname, WIN32_FILE_ATTRIBUTE_DATA *fd
}
}
/* simplify loading of DLL functions */
struct proc_addr {
const char *const dll;
const char *const function;
FARPROC pfunction;
unsigned initialized : 1;
};
/* Declares a function to be loaded dynamically from a DLL. */
#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \
static struct proc_addr proc_addr_##function = \
{ #dll, #function, NULL, 0 }; \
static rettype (WINAPI *function)(__VA_ARGS__)
/*
* Loads a function from a DLL (once-only).
* Returns non-NULL function pointer on success.
* Returns NULL + errno == ENOSYS on failure.
*/
#define INIT_PROC_ADDR(function) (function = get_proc_addr(&proc_addr_##function))
static inline void *get_proc_addr(struct proc_addr *proc)
{
/* only do this once */
if (!proc->initialized) {
proc->initialized = 1;
HANDLE hnd = LoadLibraryA(proc->dll);
if (hnd)
proc->pfunction = GetProcAddress(hnd, proc->function);
}
/* set ENOSYS if DLL or function was not found */
if (!proc->pfunction)
errno = ENOSYS;
return proc->pfunction;
}
#endif

View File

@@ -6,6 +6,7 @@
#include "../git-compat-util.h"
#include <wingdi.h>
#include <winreg.h>
#include "win32.h"
/*
ANSI codes used by git: m, K
@@ -35,26 +36,21 @@ typedef struct _CONSOLE_FONT_INFOEX {
#endif
#endif
typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL,
PCONSOLE_FONT_INFOEX);
static void warn_if_raster_font(void)
{
DWORD fontFamily = 0;
PGETCURRENTCONSOLEFONTEX pGetCurrentConsoleFontEx;
DECLARE_PROC_ADDR(kernel32.dll, BOOL, GetCurrentConsoleFontEx,
HANDLE, BOOL, PCONSOLE_FONT_INFOEX);
/* don't bother if output was ascii only */
if (!non_ascii_used)
return;
/* GetCurrentConsoleFontEx is available since Vista */
pGetCurrentConsoleFontEx = (PGETCURRENTCONSOLEFONTEX) GetProcAddress(
GetModuleHandle("kernel32.dll"),
"GetCurrentConsoleFontEx");
if (pGetCurrentConsoleFontEx) {
if (INIT_PROC_ADDR(GetCurrentConsoleFontEx)) {
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof(cfi);
if (pGetCurrentConsoleFontEx(console, 0, &cfi))
if (GetCurrentConsoleFontEx(console, 0, &cfi))
fontFamily = cfi.FontFamily;
} else {
/* pre-Vista: check default console font in registry */