patch 8.2.3208: dynamic library load error does not mention why it failed

Problem:    Dynamic library load error does not mention why it failed.
Solution:   Add the error message. (Martin Tournoij, closes #8621)
diff --git a/src/globals.h b/src/globals.h
index 4737adc..1a24512 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1632,7 +1632,7 @@
 	|| defined(DYNAMIC_MZSCHEME) \
 	|| defined(DYNAMIC_LUA) \
 	|| defined(FEAT_TERMINAL)
-EXTERN char e_loadlib[]	INIT(= N_("E370: Could not load library %s"));
+EXTERN char e_loadlib[]	INIT(= N_("E370: Could not load library %s: %s"));
 EXTERN char e_loadfunc[]	INIT(= N_("E448: Could not load library function %s"));
 #endif
 EXTERN char e_nobang[]	INIT(= N_("E477: No ! allowed"));
diff --git a/src/if_cscope.c b/src/if_cscope.c
index f52316f..815db55 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -1329,24 +1329,6 @@
 #endif
 }
 
-#ifndef UNIX
-    static char *
-GetWin32Error(void)
-{
-    char *msg = NULL;
-    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
-	    NULL, GetLastError(), 0, (LPSTR)&msg, 0, NULL);
-    if (msg != NULL)
-    {
-	// remove trailing \r\n
-	char *pcrlf = strstr(msg, "\r\n");
-	if (pcrlf != NULL)
-	    *pcrlf = '\0';
-    }
-    return msg;
-}
-#endif
-
 /*
  * Insert a new cscope database filename into the filelist.
  */
diff --git a/src/if_lua.c b/src/if_lua.c
index c19244f..82dffb0 100644
--- a/src/if_lua.c
+++ b/src/if_lua.c
@@ -105,10 +105,12 @@
 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
 # define symbol_from_dll dlsym
 # define close_dll dlclose
+# define load_dll_error dlerror
 #else
 # define load_dll vimLoadLib
 # define symbol_from_dll GetProcAddress
 # define close_dll FreeLibrary
+# define load_dll_error GetWin32Error
 #endif
 
 // lauxlib
@@ -446,7 +448,7 @@
     if (!hinstLua)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), libname);
+	    semsg(_(e_loadlib), libname, load_dll_error());
 	return FAIL;
     }
     for (reg = luaV_dll; reg->func; reg++)
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index 0c1c765..c8be940 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -668,14 +668,14 @@
     if (!hMzGC)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), gc_dll);
+	    semsg(_(e_loadlib), gc_dll, GetWin32Error());
 	return FAIL;
     }
 
     if (!hMzSch)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), sch_dll);
+	    semsg(_(e_loadlib), sch_dll, GetWin32Error());
 	return FAIL;
     }
 
diff --git a/src/if_perl.xs b/src/if_perl.xs
index 3b0fead..3d683bd 100644
--- a/src/if_perl.xs
+++ b/src/if_perl.xs
@@ -175,11 +175,13 @@
 #  define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
 #  define symbol_from_dll dlsym
 #  define close_dll dlclose
+#  define load_dll_error dlerror
 # else
 #  define PERL_PROC FARPROC
 #  define load_dll vimLoadLib
 #  define symbol_from_dll GetProcAddress
 #  define close_dll FreeLibrary
+#  define load_dll_error GetWin32Error
 # endif
 /*
  * Wrapper defines
diff --git a/src/if_python.c b/src/if_python.c
index 7f90ede..a270982 100644
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -141,10 +141,12 @@
 #  endif
 #  define close_dll dlclose
 #  define symbol_from_dll dlsym
+#  define load_dll_error dlerror
 # else
 #  define load_dll vimLoadLib
 #  define close_dll FreeLibrary
 #  define symbol_from_dll GetProcAddress
+#  define load_dll_error GetWin32Error
 # endif
 
 // This makes if_python.c compile without warnings against Python 2.5
@@ -688,7 +690,7 @@
     if (!hinstPython)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), libname);
+	    semsg(_(e_loadlib), libname, load_dll_error());
 	return FAIL;
     }
 
diff --git a/src/if_python3.c b/src/if_python3.c
index c7db9d7..4944ab8 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -125,10 +125,12 @@
 #  endif
 #  define close_dll dlclose
 #  define symbol_from_dll dlsym
+#  define load_dll_error dlerror
 # else
 #  define load_dll vimLoadLib
 #  define close_dll FreeLibrary
 #  define symbol_from_dll GetProcAddress
+#  define load_dll_error GetWin32Error
 # endif
 /*
  * Wrapper defines
@@ -795,7 +797,7 @@
     if (!hinstPy3)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), libname);
+	    semsg(_(e_loadlib), libname, load_dll_error());
 	return FAIL;
     }
 
diff --git a/src/if_ruby.c b/src/if_ruby.c
index 1d49d67..5098468 100644
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -184,11 +184,13 @@
 #  define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
 #  define symbol_from_dll dlsym
 #  define close_dll dlclose
+#  define load_dll_error dlerror
 # else
 #  define RUBY_PROC FARPROC
 #  define load_dll vimLoadLib
 #  define symbol_from_dll GetProcAddress
 #  define close_dll FreeLibrary
+#  define load_dll_error GetWin32Error
 # endif
 #endif
 
@@ -806,7 +808,7 @@
     if (!hinstRuby)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), libname);
+	    semsg(_(e_loadlib), libname, load_dll_error());
 	return FAIL;
     }
 
diff --git a/src/if_tcl.c b/src/if_tcl.c
index c3b9c5b..f3f4b07 100644
--- a/src/if_tcl.c
+++ b/src/if_tcl.c
@@ -167,11 +167,13 @@
 #  define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
 #  define symbol_from_dll dlsym
 #  define close_dll dlclose
+#  define load_dll_error dlerror
 # else
 #  define TCL_PROC FARPROC
 #  define load_dll vimLoadLib
 #  define symbol_from_dll GetProcAddress
 #  define close_dll FreeLibrary
+#  define load_dll_error GetWin32Error
 # endif
 
 /*
@@ -213,7 +215,7 @@
     if (!(hTclLib = load_dll(libname)))
     {
 	if (verbose)
-	    semsg(_(e_loadlib), libname);
+	    semsg(_(e_loadlib), libname, load_dll_error());
 	return FAIL;
     }
     for (i = 0; tcl_funcname_table[i].ptr; ++i)
diff --git a/src/mbyte.c b/src/mbyte.c
index 6fb046d..3d5ad76 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -4902,7 +4902,8 @@
 	{
 	    verbose_enter();
 	    semsg(_(e_loadlib),
-		    hIconvDLL == 0 ? DYNAMIC_ICONV_DLL : DYNAMIC_MSVCRT_DLL);
+		    hIconvDLL == 0 ? DYNAMIC_ICONV_DLL : DYNAMIC_MSVCRT_DLL,
+		    GetWin32Error());
 	    verbose_leave();
 	}
 	iconv_end();
diff --git a/src/os_win32.c b/src/os_win32.c
index eff2269..91bd18a 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -716,7 +716,7 @@
 	if (p_verbose > 0)
 	{
 	    verbose_enter();
-	    semsg(_(e_loadlib), GETTEXT_DLL);
+	    semsg(_(e_loadlib), GETTEXT_DLL, GetWin32Error());
 	    verbose_leave();
 	}
 	return 0;
@@ -8353,3 +8353,19 @@
     }
 }
 #endif
+
+    char *
+GetWin32Error(void)
+{
+    char *msg = NULL;
+    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+	    NULL, GetLastError(), 0, (LPSTR)&msg, 0, NULL);
+    if (msg != NULL)
+    {
+	// remove trailing \r\n
+	char *pcrlf = strstr(msg, "\r\n");
+	if (pcrlf != NULL)
+	    *pcrlf = '\0';
+    }
+    return msg;
+}
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index 18c8127..4d360d7 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -83,4 +83,5 @@
 int is_conpty_stable(void);
 int get_conpty_fix_type(void);
 void resize_console_buf(void);
+char * GetWin32Error(void);
 /* vim: set ft=c : */
diff --git a/src/terminal.c b/src/terminal.c
index 1f64c8b..98b4600 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -6862,8 +6862,9 @@
     if (!hWinPtyDLL)
     {
 	if (verbose)
-	    semsg(_(e_loadlib), *p_winptydll != NUL ? p_winptydll
-						       : (char_u *)WINPTY_DLL);
+	    semsg(_(e_loadlib),
+		    (*p_winptydll != NUL ? p_winptydll : (char_u *)WINPTY_DLL),
+		    GetWin32Error());
 	return FAIL;
     }
     for (i = 0; winpty_entry[i].name != NULL
diff --git a/src/version.c b/src/version.c
index 387a6e6..64622c3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3208,
+/**/
     3207,
 /**/
     3206,