X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gmodule%2Fgmodule-win32.c;h=2a35b1920e04d8075866c5126f427892b5911847;hb=2e5bd8cf47f9e1559ccc44823a2f321b8ff8c1ea;hp=0cc1bacc3694a3cc942cdbc67b0cd092b8a71743;hpb=a6149403deed931b8c78b26aeb0e9c952cf3ef93;p=platform%2Fupstream%2Fglib.git diff --git a/gmodule/gmodule-win32.c b/gmodule/gmodule-win32.c index 0cc1bac..2a35b19 100644 --- a/gmodule/gmodule-win32.c +++ b/gmodule/gmodule-win32.c @@ -1,84 +1,164 @@ /* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998 Tim Janik + * Copyright (C) 1998, 2000 Tim Janik + * + * Win32 GMODULE implementation * Copyright (C) 1998 Tor Lillqvist * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. */ + +/* + * MT safe + */ +#include "config.h" + #include #include +#include + +#ifdef G_WITH_CYGWIN +#include +#endif + +static void +set_error (const gchar *format, + ...) +{ + gchar *error; + gchar *detail; + gchar *message; + va_list args; + + error = g_win32_error_message (GetLastError ()); + + va_start (args, format); + detail = g_strdup_vprintf (format, args); + va_end (args); + + message = g_strconcat (detail, error, NULL); + + g_module_set_error (message); + g_free (message); + g_free (detail); + g_free (error); +} + /* --- functions --- */ static gpointer -_g_module_open (const gchar *file_name, - gboolean bind_lazy) +_g_module_open (const gchar *file_name, + gboolean bind_lazy, + gboolean bind_local) { HINSTANCE handle; - - handle = LoadLibrary (file_name); + wchar_t *wfilename; +#ifdef G_WITH_CYGWIN + gchar tmp[MAX_PATH]; + + cygwin_conv_to_win32_path(file_name, tmp); + file_name = tmp; +#endif + wfilename = g_utf8_to_utf16 (file_name, -1, NULL, NULL, NULL); + + handle = LoadLibraryW (wfilename); + g_free (wfilename); + if (!handle) - { - char error[100]; - sprintf (error, "Error code %d", GetLastError ()); - g_module_set_error (error); - } - + set_error ("'%s': ", file_name); + return handle; } +static gint dummy; +static gpointer null_module_handle = &dummy; + static gpointer _g_module_self (void) { - HMODULE handle; - - handle = GetModuleHandle (NULL); - if (!handle) - { - char error[100]; - sprintf (error, "Error code %d", GetLastError ()); - g_module_set_error (error); - } - - return handle; + return null_module_handle; } static void -_g_module_close (gpointer handle, - gboolean is_unref) +_g_module_close (gpointer handle, + gboolean is_unref) { - if (!FreeLibrary (handle)) + if (handle != null_module_handle) + if (!FreeLibrary (handle)) + set_error (""); +} + +static gpointer +find_in_any_module_using_toolhelp (const gchar *symbol_name) +{ + HANDLE snapshot; + MODULEENTRY32 me32; + + gpointer p; + + if ((snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0)) == (HANDLE) -1) + return NULL; + + me32.dwSize = sizeof (me32); + p = NULL; + if (Module32First (snapshot, &me32)) { - char error[100]; - sprintf (error, "Error code %d", GetLastError ()); - g_module_set_error (error); + do { + if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL) + break; + } while (Module32Next (snapshot, &me32)); } + + CloseHandle (snapshot); + + return p; } static gpointer -_g_module_symbol (gpointer handle, - const gchar *symbol_name) +find_in_any_module (const gchar *symbol_name) +{ + gpointer result; + + if ((result = find_in_any_module_using_toolhelp (symbol_name)) == NULL) + return NULL; + else + return result; +} + +static gpointer +_g_module_symbol (gpointer handle, + const gchar *symbol_name) { gpointer p; - p = GetProcAddress (handle, symbol_name); - if (!p) + if (handle == null_module_handle) { - char error[100]; - sprintf (error, "Error code %d", GetLastError ()); - g_module_set_error (error); + if ((p = GetProcAddress (GetModuleHandle (NULL), symbol_name)) == NULL) + p = find_in_any_module (symbol_name); } + else + p = GetProcAddress (handle, symbol_name); + + if (!p) + set_error (""); + return p; } @@ -86,8 +166,35 @@ static gchar* _g_module_build_path (const gchar *directory, const gchar *module_name) { - if (directory) - return g_strconcat (directory, "\\", module_name, ".dll", NULL); + gint k; + + k = strlen (module_name); + + if (directory && *directory) + if (k > 4 && g_ascii_strcasecmp (module_name + k - 4, ".dll") == 0) + return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, NULL); +#ifdef G_WITH_CYGWIN + else if (strncmp (module_name, "lib", 3) == 0 || strncmp (module_name, "cyg", 3) == 0) + return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, ".dll", NULL); + else + return g_strconcat (directory, G_DIR_SEPARATOR_S, "cyg", module_name, ".dll", NULL); +#else + else if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, ".dll", NULL); + else + return g_strconcat (directory, G_DIR_SEPARATOR_S, "lib", module_name, ".dll", NULL); +#endif + else if (k > 4 && g_ascii_strcasecmp (module_name + k - 4, ".dll") == 0) + return g_strdup (module_name); +#ifdef G_WITH_CYGWIN + else if (strncmp (module_name, "lib", 3) == 0 || strncmp (module_name, "cyg", 3) == 0) + return g_strconcat (module_name, ".dll", NULL); else + return g_strconcat ("cyg", module_name, ".dll", NULL); +#else + else if (strncmp (module_name, "lib", 3) == 0) return g_strconcat (module_name, ".dll", NULL); + else + return g_strconcat ("lib", module_name, ".dll", NULL); +#endif }