diff options
-rw-r--r-- | airpcap_loader.c | 3 | ||||
-rw-r--r-- | capture-wpcap.c | 6 | ||||
-rw-r--r-- | capture_wpcap_packet.c | 3 | ||||
-rw-r--r-- | config.nmake | 2 | ||||
-rw-r--r-- | doc/README.capture | 2 | ||||
-rw-r--r-- | epan/filesystem.c | 2 | ||||
-rwxr-xr-x | epan/wspython/wspy_libws.py | 1 | ||||
-rw-r--r-- | gtk/main.c | 2 | ||||
-rw-r--r-- | nio-ie5.c | 2 | ||||
-rw-r--r-- | wsutil/file_util.c | 114 | ||||
-rw-r--r-- | wsutil/file_util.h | 20 | ||||
-rw-r--r-- | wsutil/libwsutil.def | 2 |
12 files changed, 149 insertions, 10 deletions
diff --git a/airpcap_loader.c b/airpcap_loader.c index 65148975db..a6ef77364d 100644 --- a/airpcap_loader.c +++ b/airpcap_loader.c @@ -47,6 +47,7 @@ #include <epan/strutil.h> #include <epan/frequency-utils.h> #include "capture_ui_utils.h" +#include <wsutil/file_util.h> #include "simple_dialog.h" @@ -2450,7 +2451,7 @@ int load_airpcap(void) gboolean base_functions = TRUE; gboolean eleven_n_functions = TRUE; - if((AirpcapLib = LoadLibrary(TEXT("airpcap.dll"))) == NULL) + if((AirpcapLib = ws_load_library("airpcap.dll")) == NULL) { /* Report the error but go on */ AirpcapVersion = AIRPCAP_DLL_NOT_FOUND; diff --git a/capture-wpcap.c b/capture-wpcap.c index dbdbc9047f..2cda325136 100644 --- a/capture-wpcap.c +++ b/capture-wpcap.c @@ -36,6 +36,8 @@ #include "capture-pcap-util.h" #include "capture-pcap-util-int.h" +#include <wsutil/file_util.h> + /* XXX - yes, I know, I should move cppmagic.h to a generic location. */ #include "tools/lemon/cppmagic.h" @@ -183,7 +185,7 @@ load_wpcap(void) GModule *wh; /* wpcap handle */ const symbol_table_t *sym; - wh = g_module_open("wpcap", 0); + wh = ws_module_open("wpcap.dll", 0); if (!wh) { return; @@ -849,7 +851,7 @@ get_runtime_pcap_version(GString *str) */ if (packetVer == NULL) { packetVer = "version unknown"; - handle = g_module_open("Packet.dll", 0); + handle = ws_module_open("packet.dll", 0); if (handle != NULL) { if (g_module_symbol(handle, "PacketLibraryVersion", diff --git a/capture_wpcap_packet.c b/capture_wpcap_packet.c index 39060e8639..58e30ff42b 100644 --- a/capture_wpcap_packet.c +++ b/capture_wpcap_packet.c @@ -49,6 +49,7 @@ #include <Ntddndis.h> #include "capture_wpcap_packet.h" +#include <wsutil/file_util.h> /* packet32.h requires sockaddr_storage * whether sockaddr_storage is defined or not depends on the Platform SDK @@ -157,7 +158,7 @@ wpcap_packet_load(void) GModule *wh; /* wpcap handle */ const symbol_table_t *sym; - wh = g_module_open("packet", 0); + wh = ws_module_open("packet.dll", 0); if (!wh) { return; diff --git a/config.nmake b/config.nmake index 445924acd0..eaa3eced3b 100644 --- a/config.nmake +++ b/config.nmake @@ -156,6 +156,8 @@ NASM=$(WIRESHARK_LIBS)\nasm-2.02\nasm.exe # If you versions of Python and Visual C++ use different CRTs # comment this out. # +# XXX The DLL path in epan/wspython/wspy_libws.py likely needs to +# be fixed before this is enabled by default. #PYTHON_EMBED=1 # diff --git a/doc/README.capture b/doc/README.capture index 8ba0af49e6..5941565fcd 100644 --- a/doc/README.capture +++ b/doc/README.capture @@ -41,7 +41,7 @@ Capture driver Wireshark doesn't have direct access to the capture hardware. Instead of this, it uses the Libpcap/Winpcap library to capture data from network cards. -On Win32, in capture-wpcap.c the function g_module_open("wpcap") is called +On Win32, in capture-wpcap.c the function ws_module_open("wpcap.dll") is called to load the wpcap.dll. This dll includes all functions needed for packet capturing. diff --git a/epan/filesystem.c b/epan/filesystem.c index 2d15a9ca83..b5e149029f 100644 --- a/epan/filesystem.c +++ b/epan/filesystem.c @@ -282,7 +282,7 @@ init_progfile_dir(const char *arg0 * Attempt to get the full pathname of the currently running * program. */ - if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0) { + if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { /* * XXX - Should we use g_utf16_to_utf8(), as in * getenv_utf8()? diff --git a/epan/wspython/wspy_libws.py b/epan/wspython/wspy_libws.py index 1410f68d86..ed456f2741 100755 --- a/epan/wspython/wspy_libws.py +++ b/epan/wspython/wspy_libws.py @@ -27,6 +27,7 @@ import platform __libwireshark = None +/* XXX - We should probably return a full path here, at least on Windows. */ def get_libws_libname(): system = platform.system() if system == "Darwin": diff --git a/gtk/main.c b/gtk/main.c index 74631d460a..bb3bbdce6c 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -3116,7 +3116,7 @@ WinMain (struct HINSTANCE__ *hInstance, InitCommonControlsEx(&comm_ctrl); /* RichEd20.DLL is needed for filter entries. */ - LoadLibrary(_T("riched20.dll")); + ws_load_library("riched20.dll"); has_console = FALSE; return main (__argc, __argv); @@ -47,7 +47,7 @@ netio_ie5_connect (char const *url) if (internet == 0) { - HINSTANCE h = LoadLibrary ("wininet.dll"); + HINSTANCE h = ws_load_library("wininet.dll"); if (!h) { /* XXX - how to return an error code? */ 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 |