diff --git a/src/backend/port/dynloader/win32.c b/src/backend/port/dynloader/win32.c
index 13471df4c8416cd8bceed4db65beaa2cd6925695..c2c496a5295d2e3232e2292b383c99afbd7dd3e7 100644
--- a/src/backend/port/dynloader/win32.c
+++ b/src/backend/port/dynloader/win32.c
@@ -1,32 +1,84 @@
-/* $PostgreSQL: pgsql/src/backend/port/dynloader/win32.c,v 1.5 2004/12/02 19:38:50 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/backend/port/dynloader/win32.c,v 1.6 2005/08/12 21:23:10 momjian Exp $ */
 
 #include <windows.h>
+#include <stdio.h>
 
 char *dlerror(void);
 int dlclose(void *handle);
 void *dlsym(void *handle, const char *symbol);
 void *dlopen(const char *path, int mode);
 
+static char last_dyn_error[512];
+
+static void set_dl_error(void)
+{
+	DWORD err = GetLastError();
+
+	if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
+				FORMAT_MESSAGE_FROM_SYSTEM,
+				NULL,
+				err,
+				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+				last_dyn_error,
+				sizeof(last_dyn_error)-1,
+				NULL) == 0)
+	{
+		snprintf(last_dyn_error, sizeof(last_dyn_error)-1,
+				"unknown error %lu", err);
+	}	
+}
+
 char *
 dlerror(void)
 {
-	return "dynamic load error";
+	if (last_dyn_error[0])
+		return last_dyn_error;
+	else
+		return NULL;
 }
 
 int
 dlclose(void *handle)
 {
-	return FreeLibrary((HMODULE) handle) ? 0 : 1;
+	if (!FreeLibrary((HMODULE) handle))
+	{
+		set_dl_error();
+		return 1;
+	}
+	last_dyn_error[0] = 0;
+	return 0;
 }
 
 void *
 dlsym(void *handle, const char *symbol)
 {
-	return (void *) GetProcAddress((HMODULE) handle, symbol);
+	void *ptr;
+	ptr = GetProcAddress((HMODULE) handle, symbol);
+	if (!ptr) 
+	{
+		set_dl_error();
+		return NULL;
+	}
+	last_dyn_error[0] = 0;
+	return ptr;
 }
 
 void *
 dlopen(const char *path, int mode)
 {
-	return (void *) LoadLibrary(path);
+	HMODULE h;
+	int prevmode;
+
+	/* Disable popup error messages when loading DLLs */
+	prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+	h = LoadLibrary(path);
+	SetErrorMode(prevmode);
+	
+	if (!h) 
+	{
+		set_dl_error();
+		return NULL;
+	}
+	last_dyn_error[0] = 0;
+	return (void *) h;
 }