From 7d781c62b1dfe9cabbc57156581799b3150ab317 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 12 Aug 2005 21:23:10 +0000 Subject: [PATCH] [ backpatched to 8.0.X.] > >> 3) I restarted the postmaster both times. I got this error > both times. > >> :25: ERROR: could not load library "C:/Program > >> Files/PostgreSQL/8.0/lib/testtrigfuncs.dll": dynamic load error > > > Yes. We really need to look at fixing that error message. I had > > forgotten it completely :-( > > > Bruce, you think we can sneak that in after feature freeze? I would > > call it a bugfix :-) > > Me too. That's been on the radar for awhile --- please do > send in a patch. Here we go, that wasn't too hard :-) Apart from adding the error handling, it does one more thing: it changes the errormode when loading the DLLs. Previously if a DLL was broken, or referenced other DLLs that couldn't be found, a popup dialog box would appear on the screen. Which had to be clicked before the backend could continue. This patch also disables the popup error message for DLL loads. I think this is something we should consider doing for the entire backend - disable those popups, and say we deal with it ourselves. What do you other win32 hackers thinnk about this? In the meantime, this patch fixes the error msgs. Please apply for 8.1 and please consider a backpatch to 8.0. Magnus Hagander --- src/backend/port/dynloader/win32.c | 62 +++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/src/backend/port/dynloader/win32.c b/src/backend/port/dynloader/win32.c index 13471df4c8..c2c496a529 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 +#include 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; }