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; }