Add ws_load_library and ws_module_open, which respectively call
[obnox/wireshark/wip.git] / wsutil / file_util.c
index 59a5b50ddec7ce260ca2d4bd46bbd3bdf4d8e815..0c57efbe19e36df82379ae57e897b4254dc5e294 100644 (file)
@@ -48,8 +48,8 @@
 
 #include "file_util.h"
 
-
-
+static gchar *program_path = NULL;
+static gchar *system_path = NULL;
 
 /**
  * g_open:
@@ -226,7 +226,7 @@ ws_stdio_stat (const gchar *filename,
       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
       int retval;
       int save_errno;
-      int len;
+      size_t len;
 
       if (wfilename == NULL)
        {
@@ -234,11 +234,11 @@ ws_stdio_stat (const gchar *filename,
          return -1;
        }
 
-      len = (int) wcslen (wfilename);
+      len = wcslen (wfilename);
       while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
        len--;
       if (len > 0 &&
-         (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
+         (!g_path_is_absolute (filename) || len > (size_t) (g_path_skip_root (filename) - filename)))
        wfilename[len] = '\0';
 
       retval = _wstat (wfilename, (struct _stat *) buf);
@@ -249,7 +249,6 @@ ws_stdio_stat (const gchar *filename,
       errno = save_errno;
       return retval;
 }
-
 /**
  * g_unlink:
  * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
@@ -268,23 +267,24 @@ ws_stdio_stat (const gchar *filename,
  *
  * Since: 2.6
  */
 int
 ws_stdio_unlink (const gchar *filename)
 {
-      gchar *cp_filename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
+      wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
       int retval;
       int save_errno;
 
-      if (cp_filename == NULL)
+      if (wfilename == NULL)
        {
          errno = EINVAL;
          return -1;
        }
 
-      retval = unlink (cp_filename);
+      retval = _wunlink (wfilename);
       save_errno = errno;
 
-      g_free (cp_filename);
+      g_free (wfilename);
 
       errno = save_errno;
       return retval;
@@ -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