diff options
author | Gerald Combs <gerald@wireshark.org> | 2010-08-25 20:30:59 +0000 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2010-08-25 20:30:59 +0000 |
commit | 607b228df6f1f754bf9bda6cfa21563913b1e7ff (patch) | |
tree | 6d1cf5c9dae154869fc6a13d181489834d7a190e /wsutil | |
parent | 43af5f6344d47af3ccfa574c1013dbc6a011904c (diff) |
Add ws_load_library and ws_module_open, which respectively call
LoadLibrary and g_module_open only for the program directory and system
directory on Windows. Use them to replace a bunch of LoadLibrary and
g_module_open calls. Use the extension ".dll" for all the DLLs that we
load. Add comments about DLL loading in Python.
svn path=/trunk/; revision=33924
Diffstat (limited to 'wsutil')
-rw-r--r-- | wsutil/file_util.c | 114 | ||||
-rw-r--r-- | wsutil/file_util.h | 20 | ||||
-rw-r--r-- | wsutil/libwsutil.def | 2 |
3 files changed, 134 insertions, 2 deletions
diff --git a/wsutil/file_util.c b/wsutil/file_util.c index d145752c83..0c57efbe19 100644 --- a/wsutil/file_util.c +++ b/wsutil/file_util.c @@ -48,8 +48,8 @@ #include "file_util.h" - - +static gchar *program_path = NULL; +static gchar *system_path = NULL; /** * g_open: @@ -441,3 +441,113 @@ ws_stdio_freopen (const gchar *filename, errno = save_errno; return retval; } + + +/* DLL loading */ +static gboolean +init_dll_load_paths() { + TCHAR path_pfx[MAX_PATH]; + + if (program_path && system_path) + return TRUE; + + /* XXX - Duplicate code in filesystem.c:init_progfile_dir */ + if (GetModuleFileName(NULL, path_pfx, MAX_PATH) == 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return FALSE; + } + + if (!program_path) { + program_path = g_utf16_to_utf8(path_pfx, -1, NULL, NULL, NULL); + } + + if (GetSystemDirectory(path_pfx, MAX_PATH) == 0) { + return FALSE; + } + + if (!system_path) { + system_path = g_utf16_to_utf8(path_pfx, -1, NULL, NULL, NULL); + } + + if (program_path && system_path) + return TRUE; + + return FALSE; +} + +/* + * Internally g_module_open uses LoadLibrary on Windows and returns an + * HMODULE cast to a GModule *. However there's no guarantee that this + * will always be the case, so we call LoadLibrary and g_module_open + * separately. + */ + +void * +ws_load_library(gchar *library_name) { + gchar *full_path; + wchar_t *full_path_w; + HMODULE dll_h; + + if (!init_dll_load_paths() || !library_name) + return NULL; + + /* First try the program directory */ + full_path = g_module_build_path(program_path, library_name); + full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL); + + if (full_path && full_path_w) { + dll_h = LoadLibraryW(full_path_w); + if (dll_h) { + g_free(full_path); + g_free(full_path_w); + return dll_h; + } + } + + /* Next try the system directory */ + full_path = g_module_build_path(system_path, library_name); + full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL); + + if (full_path && full_path_w) { + dll_h = LoadLibraryW(full_path_w); + if (dll_h) { + g_free(full_path); + g_free(full_path_w); + return dll_h; + } + } + + return NULL; +} + +GModule * +ws_module_open(gchar *module_name, GModuleFlags flags) { + gchar *full_path; + GModule *mod; + + if (!init_dll_load_paths() || !module_name) + return NULL; + + /* First try the program directory */ + full_path = g_module_build_path(program_path, module_name); + + if (full_path) { + mod = g_module_open(full_path, flags); + if (mod) { + g_free(full_path); + return mod; + } + } + + /* Next try the system directory */ + full_path = g_module_build_path(system_path, module_name); + + if (full_path) { + mod = g_module_open(full_path, flags); + if (mod) { + g_free(full_path); + return mod; + } + } + + return NULL; +}
\ No newline at end of file diff --git a/wsutil/file_util.h b/wsutil/file_util.h index e7ee04259f..bf5689905a 100644 --- a/wsutil/file_util.h +++ b/wsutil/file_util.h @@ -33,6 +33,7 @@ extern "C" { #ifdef _WIN32 #include <io.h> +#include <gmodule.h> #endif #ifdef HAVE_SYS_STAT_H @@ -114,6 +115,25 @@ extern FILE * ws_stdio_freopen (const gchar *filename, const gchar *mode, FILE * #define ws_dir_rewind g_dir_rewind #define ws_dir_close g_dir_close +/* DLL loading */ + +/** Load a DLL using LoadLibrary. + * Only the system and program directories are searched. + * + * @param library_name The name of the DLL. + * @return A handle to the DLL if found, NULL on failure. + */ + +void *ws_load_library(gchar *library_name); +/** Load a DLL using g_module_open. + * Only the system and program directories are searched. + * + * @param module_name The name of the DLL. + * @param flags Flags to be passed to g_module_open. + * @return A handle to the DLL if found, NULL on failure. + */ +GModule *ws_module_open(gchar *module_name, GModuleFlags flags); + /* XXX - remove include "dirent.h" */ /* XXX - remove include "direct.h" */ /* XXX - remove include "sys/stat.h" */ diff --git a/wsutil/libwsutil.def b/wsutil/libwsutil.def index 2cbe0852b0..a0cafe95fc 100644 --- a/wsutil/libwsutil.def +++ b/wsutil/libwsutil.def @@ -18,6 +18,8 @@ ws_stdio_remove ws_stdio_rename ws_stdio_stat ws_stdio_unlink +ws_load_library +ws_module_open ; inet_aton.c inet_aton |