I'm at the win32 error messages once more. The DLL load thingy doesn't
authorBruce Momjian
Wed, 24 Apr 2002 02:26:06 +0000 (02:26 +0000)
committerBruce Momjian
Wed, 24 Apr 2002 02:26:06 +0000 (02:26 +0000)
work on all win9x machines, so i made it go thru a l ookup table
instead, using the DLL as last resort.  I also moved this out of the
fe-misc.c file because of the size of the lookup ta ble. Who knows, we
might add more other win32 specific code there in the future.

I also fixed a small typo in the pg_config.h.win32 that made the
compiler compla in about the gnu snprintf declaration.

I tried to make this patch with psql coding style. I've successfully
tested this on win2k and win98 and it works fine (i.e. the mes sage
shows on win98 too, it didn't with the old implementation).

Magnus Naeslund

src/include/pg_config.h.win32
src/interfaces/libpq/fe-misc.c
src/interfaces/libpq/win32.c [new file with mode: 0644]
src/interfaces/libpq/win32.mak

index 0681c717cb5af8e1c19a718a6762c1553a800cb9..b750a3a097b5a4d60f1b0be31a3bfb701cf94baf 100644 (file)
@@ -28,7 +28,7 @@
 #define HAVE_NAMESPACE_STD
 
 /* use _snprintf instead of snprintf */
-#define    HAVE_SNPRINTF_DECL
+#define    HAVE_DECL_SNPRINTF 1
 #define snprintf   _snprintf
 
 /* defines for dynamic linking on Win32 platform */
index 190d378fd9a2485c910ae78f7725ee3509abf7e9..643c81055fc5eb6e072ab8dadf941462de2a6505 100644 (file)
@@ -25,7 +25,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.69 2002/04/15 23:34:17 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.70 2002/04/24 02:26:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,8 +37,6 @@
 #include 
 
 #ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include 
 #include "win32.h"
 #else
 #include 
@@ -894,46 +892,3 @@ libpq_gettext(const char *msgid)
    return dgettext("libpq", msgid);
 }
 #endif   /* ENABLE_NLS */
-
-#ifdef WIN32
-/*
- * strerror replacement for windows:
- *
- * This works on WIN2000 and newer, but we don't know where to find WinSock
- * error strings on older Windows flavors.  If you know, clue us in.
- */
-const char *
-winsock_strerror(int eno)
-{
-   static char err_buf[512];
-#define WSSE_MAXLEN (sizeof(err_buf)-1-13) /* 13 for " (0x00000000)" */
-   int         length;
-
-   /* First try the "system table", this works on Win2k and up */
-
-   if (FormatMessage(
-               FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
-                     0,
-                     eno,
-                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                     err_buf,
-                     WSSE_MAXLEN,
-                     NULL))
-       goto WSSE_GOODEXIT;
-
-   /* Insert other possible lookup methods here ... */
-
-   /* Everything failed, just tell the user that we don't know the desc */
-
-   strcpy(err_buf, "Socket error, no description available.");
-
-WSSE_GOODEXIT:
-
-   length = strlen(err_buf);
-   sprintf(err_buf + (length < WSSE_MAXLEN ? length : WSSE_MAXLEN),
-           " (0x%08X)", eno);
-
-   return err_buf;
-}
-
-#endif
diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c
new file mode 100644 (file)
index 0000000..9c7d379
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * FILE
+ *     win32.c
+ *
+ * DESCRIPTION
+ *     Win32 support functions.
+ *
+ * Contains table and functions for looking up win32 socket error
+ * descriptions. But will/may contain other win32 helper functions
+ * for libpq.
+ *
+ * The error constants are taken from the Frambak Bakfram LGSOCKET 
+ * library guys who in turn took them from the Winsock FAQ.
+ *
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
+#include "win32.h"
+
+static struct WSErrorEntry {
+    DWORD   error;
+    const char*  description;
+} WSErrors [] = {
+    {0,                  "No error"},
+    {WSAEINTR,           "Interrupted system call"},
+    {WSAEBADF,           "Bad file number"},
+    {WSAEACCES,          "Permission denied"},
+    {WSAEFAULT,          "Bad address"},
+    {WSAEINVAL,          "Invalid argument"},
+    {WSAEMFILE,          "Too many open sockets"},
+    {WSAEWOULDBLOCK,     "Operation would block"},
+    {WSAEINPROGRESS,     "Operation now in progress"},
+    {WSAEALREADY,        "Operation already in progress"},
+    {WSAENOTSOCK,        "Socket operation on non-socket"},
+    {WSAEDESTADDRREQ,    "Destination address required"},
+    {WSAEMSGSIZE,        "Message too long"},
+    {WSAEPROTOTYPE,      "Protocol wrong type for socket"},
+    {WSAENOPROTOOPT,     "Bad protocol option"},
+    {WSAEPROTONOSUPPORT, "Protocol not supported"},
+    {WSAESOCKTNOSUPPORT, "Socket type not supported"},
+    {WSAEOPNOTSUPP,      "Operation not supported on socket"},
+    {WSAEPFNOSUPPORT,    "Protocol family not supported"},
+    {WSAEAFNOSUPPORT,    "Address family not supported"},
+    {WSAEADDRINUSE,      "Address already in use"},
+    {WSAEADDRNOTAVAIL,   "Can't assign requested address"},
+    {WSAENETDOWN,        "Network is down"},
+    {WSAENETUNREACH,     "Network is unreachable"},
+    {WSAENETRESET,       "Net connection reset"},
+    {WSAECONNABORTED,    "Software caused connection abort"},
+    {WSAECONNRESET,      "Connection reset by peer"},
+    {WSAENOBUFS,         "No buffer space available"},
+    {WSAEISCONN,         "Socket is already connected"},
+    {WSAENOTCONN,        "Socket is not connected"},
+    {WSAESHUTDOWN,       "Can't send after socket shutdown"},
+    {WSAETOOMANYREFS,    "Too many references, can't splice"},
+    {WSAETIMEDOUT,       "Connection timed out"},
+    {WSAECONNREFUSED,    "Connection refused"},
+    {WSAELOOP,           "Too many levels of symbolic links"},
+    {WSAENAMETOOLONG,    "File name too long"},
+    {WSAEHOSTDOWN,       "Host is down"},
+    {WSAEHOSTUNREACH,    "No route to host"},
+    {WSAENOTEMPTY,       "Directory not empty"},
+    {WSAEPROCLIM,        "Too many processes"},
+    {WSAEUSERS,          "Too many users"},
+    {WSAEDQUOT,          "Disc quota exceeded"},
+    {WSAESTALE,          "Stale NFS file handle"},
+    {WSAEREMOTE,         "Too many levels of remote in path"},
+    {WSASYSNOTREADY,     "Network system is unavailable"},
+    {WSAVERNOTSUPPORTED, "Winsock version out of range"},
+    {WSANOTINITIALISED,  "WSAStartup not yet called"},
+    {WSAEDISCON,         "Graceful shutdown in progress"},
+    {WSAHOST_NOT_FOUND,  "Host not found"},
+    {WSATRY_AGAIN,       "NA Host not found / SERVFAIL"},
+    {WSANO_RECOVERY,     "Non recoverable FORMERR||REFUSED||NOTIMP"},
+    {WSANO_DATA,         "No host data of that type was found"},
+    {0,0} /* End of table */
+};
+
+
+/* 
+ * Returns 0 if not found, linear but who cares, at this moment
+ * we're already in pain :)
+ */
+
+static int LookupWSErrorMessage(DWORD err,char*dest)
+{   
+  struct WSErrorEntry *e;
+  for (e = WSErrors;e->description;e++)
+  {
+    if (e->error == err)
+    {
+      strcpy(dest,e->description);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+struct MessageDLL{
+    const char *dll_name;
+    void       *handle;
+    int         loaded; /* BOOL */
+}dlls[]={
+  {"netmsg.dll",0,0},
+  {"winsock.dll",0,0},
+  {"wsock32.dll",0,0},
+  {"ws2_32.dll",0,0},
+  {"wsock32n.dll",0,0},
+  {"mswsock.dll",0,0},
+  {"ws2help.dll",0,0},
+  {"ws2thk.dll",0,0},
+  {0,0,1}             /* Last one, no dll, always loaded */
+};
+
+#define DLLS_SIZE (sizeof(dlls)/sizeof(struct MessageDLL))
+
+/*
+ * Returns a description of the socket error by first trying
+ * to find it in the lookup table, and if that fails, tries
+ * to load any of the winsock dlls to find that message.
+ * The DLL thing works from Nt4 (spX ?) up, but some special 
+ * versions of winsock might have this aswell (seen on Win98 SE
+ * special install)            / Magnus Naeslund ([email protected])
+ *
+ */
+
+const char *winsock_strerror(int err){
+  static char   buf[512]; /* Not threadsafe */
+  unsigned long flags;
+  int           offs,i;
+  int           success = LookupWSErrorMessage(err,buf);
+  
+  for (i=0;!success && i
+  {
+      
+      if (!dlls[i].loaded)
+      {
+   dlls[i].loaded = 1; /* Only load once */
+   dlls[i].handle = (void*)LoadLibraryEx(
+                         dlls[i].dll_name,
+                         0,
+                         LOAD_LIBRARY_AS_DATAFILE);
+      }
+      
+      if (dlls[i].dll_name && !dlls[i].handle)
+   continue; /* Didn't load */
+      
+      flags = FORMAT_MESSAGE_FROM_SYSTEM 
+       | FORMAT_MESSAGE_IGNORE_INSERTS
+       | (dlls[i].handle?FORMAT_MESSAGE_FROM_HMODULE:0);
+      
+      success = 0 != FormatMessage( 
+                  flags,
+                  dlls[i].handle,err,
+                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                  buf,sizeof(buf)-64,
+                  0
+                  );
+  }
+  
+  if (!success)
+  {
+    sprintf(buf,"Unknown socket error (0x%08X/%lu)",err,err);
+  }
+  else
+  {
+    buf[sizeof(buf)-1]='\0';
+    offs = strlen(buf);
+    if (offs>sizeof(buf)-64)
+      offs = sizeof(buf)-64;
+    sprintf(buf+offs," (0x%08X/%lu)",err,err);
+  }
+  return buf;  
+}
+
index ea433eafac3a62a8240716da61a224151249d709..98b4e986ef9401c854bc24aa1365a884878bb50f 100644 (file)
@@ -64,6 +64,7 @@ CLEAN :
    -@erase "$(INTDIR)\fe-print.obj"
    -@erase "$(INTDIR)\pqexpbuffer.obj"
    -@erase "$(OUTDIR)\libpqdll.obj"
+   -@erase "$(OUTDIR)\win32.obj"
    -@erase "$(OUTDIR)\libpq.lib"
    -@erase "$(OUTDIR)\libpq.dll"
    -@erase "$(OUTDIR)\libpq.res"
@@ -96,6 +97,7 @@ CPP_SBRS=.
 LIB32=link.exe -lib
 LIB32_FLAGS=/nologo /out:"$(OUTDIR)\libpq.lib" 
 LIB32_OBJS= \
+   "$(OUTDIR)\win32.obj" \
    "$(INTDIR)\dllist.obj" \
    "$(INTDIR)\md5.obj" \
    "$(INTDIR)\fe-auth.obj" \
@@ -113,9 +115,8 @@ LIB32_OBJS = $(LIB32_OBJS) "$(INTDIR)\wchar.obj" "$(INTDIR)\encnames.obj"
 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libpq.res"
 
 LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib wsock32.lib\
- odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
+LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib wsock32.lib\
+ /nologo /subsystem:windows /dll /incremental:no\
  /pdb:"$(OUTDIR)\libpqdll.pdb" /machine:I386 /out:"$(OUTDIR)\libpq.dll"\
  /implib:"$(OUTDIR)\libpqdll.lib"  /def:libpqdll.def
 LINK32_OBJS= \