Add ws_load_library and ws_module_open, which respectively call
authorgerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 25 Aug 2010 20:30:59 +0000 (20:30 +0000)
committergerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 25 Aug 2010 20:30:59 +0000 (20:30 +0000)
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.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@33924 f5534014-38df-0310-8fa8-9805f1628bb7

12 files changed:
airpcap_loader.c
capture-wpcap.c
capture_wpcap_packet.c
config.nmake
doc/README.capture
epan/filesystem.c
epan/wspython/wspy_libws.py
gtk/main.c
nio-ie5.c
wsutil/file_util.c
wsutil/file_util.h
wsutil/libwsutil.def

index 6514897..a6ef773 100644 (file)
@@ -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;
index dbdbc90..2cda325 100644 (file)
@@ -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",
index 39060e8..58e30ff 100644 (file)
@@ -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;
index 445924a..eaa3ece 100644 (file)
@@ -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
 
 #
index 8ba0af4..5941565 100644 (file)
@@ -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.
 
index 2d15a9c..b5e1490 100644 (file)
@@ -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()?
index 1410f68..ed456f2 100755 (executable)
@@ -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":
index 74631d4..bb3bbdc 100644 (file)
@@ -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);
index 97cf62e..19267bf 100644 (file)
--- a/nio-ie5.c
+++ b/nio-ie5.c
@@ -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? */
index d145752..0c57efb 100644 (file)
@@ -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
index e7ee042..bf56899 100644 (file)
@@ -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" */
index 2cbe085..a0cafe9 100644 (file)
@@ -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