diff liboctave/util/oct-shlib.cc @ 27700:6455c82d5180

When loading a library display error message from OS on Windows (bug #57202). * oct-shlib.cc (octave_w32_shlib::octave_w32_shlib): Get error message from system resources.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 16 Nov 2019 15:13:12 +0100
parents 3db033e86376
children 847dece1ae10
line wrap: on
line diff
--- a/liboctave/util/oct-shlib.cc	Sat Nov 16 01:04:30 2019 -0500
+++ b/liboctave/util/oct-shlib.cc	Sat Nov 16 15:13:12 2019 +0100
@@ -287,13 +287,6 @@
     HINSTANCE m_handle;
   };
 
-  static void
-  set_dll_directory (const std::string& dir = "")
-  {
-    SetDllDirectoryW (dir.empty ()
-                      ? nullptr : sys::u8_to_wstring (dir).c_str ());
-  }
-
   octave_w32_shlib::octave_w32_shlib (const std::string& f)
     : dynamic_library::dynlib_rep (f), m_handle (nullptr)
   {
@@ -304,38 +297,39 @@
       }
 
     std::string dir = sys::file_ops::dirname (f);
-
-    set_dll_directory (dir);
+    SetDllDirectoryW (dir.empty ()
+                      ? nullptr : sys::u8_to_wstring (dir).c_str ());
 
     m_handle = LoadLibraryW (sys::u8_to_wstring (m_file).c_str ());
 
-    set_dll_directory ();
+    SetDllDirectoryW (nullptr);
 
     if (! m_handle)
       {
-        DWORD lastError = GetLastError ();
-        const char *msg;
+        DWORD last_error = GetLastError ();
 
-        switch (lastError)
-          {
-          case ERROR_MOD_NOT_FOUND:
-          case ERROR_DLL_NOT_FOUND:
-            msg = "could not find library or dependencies";
-            break;
+        wchar_t *error_text = nullptr;
+        FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
+                        FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                        FORMAT_MESSAGE_IGNORE_INSERTS,
+                        nullptr, last_error,
+                        MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+                        reinterpret_cast <wchar_t *> (&error_text), 0, nullptr);
 
-          case ERROR_INVALID_DLL:
-            msg = "library or its dependencies are damaged";
-            break;
-
-          case ERROR_DLL_INIT_FAILED:
-            msg = "library initialization routine failed";
-            break;
-
-          default:
-            msg = "library open failed";
+        std::string msg = "opening the library '" + m_file + "' failed: ";
+        if (error_text != nullptr)
+          {
+            msg.append (sys::u8_from_wstring (error_text));
+            LocalFree (error_text);
+          }
+        else
+          {
+            std::ostringstream err_str;
+            err_str << "Unknown error (" << last_error << ").";
+            msg.append (err_str.str ());
           }
 
-        (*current_liboctave_error_handler) ("%s: %s", msg, m_file.c_str ());
+        (*current_liboctave_error_handler) ("%s", msg.c_str ());
       }
   }