Den 2010-01-02 10:34 skrev Peter Rosin:
Hi!

Here's another patch, it makes use of the new function GetErrorMode,
if available, instead of cludging it by calling SetErrorMode twice.
GetErrorMode was introduced with Windows Vista.

This patch does not apply cleanly to a clean git repo, it changes
lines too close to the previous error reporting patch(es), but it
is orthogonal.

Oops, forgot the patch...

Cheers,
Peter

2010-01-02  Peter Rosin  <p...@lysator.liu.se>

        Use GetErrorMode if it is available.
        * libltdl/loaders/loadlibrary.c (wrap_geterrormode): New
        function that checks if GetErrorMode is supported by the
        system and makes use of it if it is.
        (fallback_geterrormode): New function that is used otherwise
        that implements the old workaround.
        (geterrormode): New function pointer that points at either
        of the above or directly at GetErrorMode.
        (vm_open): Make use of the above.

diff --git a/libltdl/loaders/loadlibrary.c b/libltdl/loaders/loadlibrary.c
index 3e65212..759b50a 100644
--- a/libltdl/loaders/loadlibrary.c
+++ b/libltdl/loaders/loadlibrary.c
@@ -104,7 +104,12 @@ get_vtable (lt_user_data loader_data)
 #define LOADLIB_SETERROR(errcode) LOADLIB__SETERROR (LT__STRERROR (errcode))
 
 static const char *loadlibraryerror (const char *default_errmsg);
+static UINT WINAPI wrap_geterrormode (void);
+static UINT WINAPI fallback_geterrormode (void);
 
+typedef UINT (WINAPI geterrormode_type) (void);
+
+static geterrormode_type *geterrormode = wrap_geterrormode;
 static char *error_message = 0;
 
 
@@ -181,16 +186,14 @@ vm_open (lt_user_data LT__UNUSED loader_data, const char 
*filename,
     }
 
   {
-    /* Silence dialog from LoadLibrary on some failures.
-       No way to get the error mode, but to set it,
-       so set it twice to preserve any previous flags. */
-    UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
-    SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
+    /* Silence dialog from LoadLibrary on some failures. */
+    UINT errormode = geterrormode ();
+    SetErrorMode (errormode | SEM_FAILCRITICALERRORS);
 
     module = LoadLibrary (wpath);
 
     /* Restore the error mode. */
-    SetErrorMode(errormode);
+    SetErrorMode (errormode);
   }
 
   /* libltdl expects this function to fail if it is unable
@@ -286,3 +289,29 @@ loadlibraryerror (const char *default_errmsg)
 
   return error_message ? error_message : default_errmsg;
 }
+
+/* A function called through the geterrormode variable which checks
+   if the system supports GetErrorMode and arranges for it or a
+   fallback implementation to be called directly in the future. The
+   selected version is then called. */
+static UINT WINAPI
+wrap_geterrormode (void)
+{
+  HMODULE kernel32 = GetModuleHandleA ("kernel32.dll");
+  geterrormode = (geterrormode_type *) GetProcAddressA (kernel32,
+                                                        "GetErrorMode");
+  if (!geterrormode)
+    geterrormode = fallback_geterrormode;
+  return geterrormode ();
+}
+
+/* A function called through the geterrormode variable for cases
+   where the system does not support GetErrorMode */
+static UINT WINAPI
+fallback_geterrormode (void)
+{
+  /* Prior to Windows Vista, the only way to get the current error
+     mode was to set a new one. In our case, we are setting a new
+     error mode right after "getting" it, so that's fairly ok. */
+  return SetErrorMode (SEM_FAILCRITICALERRORS);
+}

Reply via email to