diff --git a/libltdl/loaders/loadlibrary.c b/libltdl/loaders/loadlibrary.c index 97fddf4..3c08f2e 100644 --- a/libltdl/loaders/loadlibrary.c +++ b/libltdl/loaders/loadlibrary.c @@ -1,7 +1,7 @@ /* loader-loadlibrary.c -- dynamic linking for Win32 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2010 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -98,12 +98,23 @@ get_vtable (lt_user_data loader_data) #include +#define LOCALFREE(mem) LT_STMT_START { \ + if (mem) { LocalFree ((void *)mem); mem = NULL; } } LT_STMT_END +#define LOADLIB__SETERROR(errmsg) LT__SETERRORSTR (loadlibraryerror (errmsg)) +#define LOADLIB_SETERROR(errcode) LOADLIB__SETERROR (LT__STRERROR (errcode)) + +static const char *loadlibraryerror (const char *default_errmsg); + +static char *error_message = 0; + + /* A function called through the vtable when this loader is no longer needed by the application. */ static int vl_exit (lt_user_data LT__UNUSED loader_data) { vtable = NULL; + LOCALFREE (error_message); return 0; } @@ -209,7 +220,7 @@ vm_open (lt_user_data LT__UNUSED loader_data, const char *filename, if (cur || !module) { - LT__SETERROR (CANNOT_OPEN); + LOADLIB_SETERROR (CANNOT_OPEN); module = 0; } } @@ -225,9 +236,9 @@ vm_close (lt_user_data LT__UNUSED loader_data, lt_module module) { int errors = 0; - if (FreeLibrary((HMODULE) module) == 0) + if (FreeLibrary ((HMODULE) module) == 0) { - LT__SETERROR (CANNOT_CLOSE); + LOADLIB_SETERROR (CANNOT_CLOSE); ++errors; } @@ -244,8 +255,32 @@ vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name) if (!address) { - LT__SETERROR (SYMBOL_NOT_FOUND); + LOADLIB_SETERROR (SYMBOL_NOT_FOUND); } return address; } + + + +/* --- HELPER FUNCTIONS --- */ + + +/* Return the windows error message, or the passed in error message on + failure. */ +static const char * +loadlibraryerror (const char *default_errmsg) +{ + LOCALFREE (error_message); + + FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + 0, + (char *) &error_message, + 0, NULL); + + return error_message ? error_message : default_errmsg; +}