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  <p...@lysator.liu.se>

        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;
+}

Reply via email to