aboutsummaryrefslogtreecommitdiffstats
path: root/wsutil
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2010-08-25 20:30:59 +0000
committerGerald Combs <gerald@wireshark.org>2010-08-25 20:30:59 +0000
commit607b228df6f1f754bf9bda6cfa21563913b1e7ff (patch)
tree6d1cf5c9dae154869fc6a13d181489834d7a190e /wsutil
parent43af5f6344d47af3ccfa574c1013dbc6a011904c (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.c114
-rw-r--r--wsutil/file_util.h20
-rw-r--r--wsutil/libwsutil.def2
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