X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gmodule%2Fgmodule-win32.c;h=2a35b1920e04d8075866c5126f427892b5911847;hb=9da85c7262325478e8730ae9f3e76bd0528a9a8c;hp=8d021e109002480ff2a3d8ca76769117f16b6d22;hpb=5991248acf6010a95c0e9f2666ee19cd8fd7ccd1;p=platform%2Fupstream%2Fglib.git diff --git a/gmodule/gmodule-win32.c b/gmodule/gmodule-win32.c index 8d021e1..2a35b19 100644 --- a/gmodule/gmodule-win32.c +++ b/gmodule/gmodule-win32.c @@ -1,27 +1,25 @@ /* GMODULE - GLIB wrapper code for dynamic module loading * Copyright (C) 1998, 2000 Tim Janik * - * WIN32 GMODULE implementation + * 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-1999. See the AUTHORS + * 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/. @@ -30,57 +28,118 @@ /* * 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) + 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) - { - gchar error[100]; + set_error ("'%s': ", file_name); - sprintf (error, "Error code %d", GetLastError ()); - g_module_set_error (error); - } - return handle; } +static gint dummy; +static gpointer null_module_handle = &dummy; + static gpointer _g_module_self (void) { - HMODULE handle; - - handle = GetModuleHandle (NULL); - if (!handle) - { - gchar 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) { - if (!FreeLibrary (handle)) - { - gchar error[100]; + 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; - sprintf (error, "Error code %d", GetLastError ()); - g_module_set_error (error); + if ((snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0)) == (HANDLE) -1) + return NULL; + + me32.dwSize = sizeof (me32); + p = NULL; + if (Module32First (snapshot, &me32)) + { + do { + if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL) + break; + } while (Module32Next (snapshot, &me32)); } + + CloseHandle (snapshot); + + return p; +} + +static gpointer +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 @@ -89,15 +148,17 @@ _g_module_symbol (gpointer handle, { gpointer p; - p = GetProcAddress (handle, symbol_name); - if (!p) + if (handle == null_module_handle) { - gchar 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; } @@ -106,15 +167,34 @@ _g_module_build_path (const gchar *directory, const gchar *module_name) { gint k; - + k = strlen (module_name); + if (directory && *directory) - if (k > 4 && g_strcasecmp (module_name + k - 4, ".dll") == 0) - return g_strconcat (directory, "\\", module_name, NULL); + 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, "\\", module_name, ".dll", NULL); - else if (k > 4 && g_strcasecmp (module_name + k - 4, ".dll") == 0) + 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 }