Hi!
Please consider the attached patch.
I'm just about to go skiing for a week or so, so I'll push when I get
back if this patch is blessed (knock wood) after I leave...
Cheers,
Peter
ChangeLog:
2010-01-02 Peter Rosin <[email protected]>
Report proper errors from the loadlibrary loader.
* libltdl/loaders/loadlibrary.c: Update copyright years.
(loadlibraryerror): New helper function that returns the
latest Windows error as a string, or the provided default
string on failure to do so.
(LOADLIB_SETERROR): New macro that wraps previous to make it
easy to use.
(vm_open, vm_close, vm_sym): Make use of previous.
(LOCALFREE): New macro to help free the Windows error string.
(vl_exit): Make use of previous.
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 <windows.h>
+#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;
+}