diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c
index d22907967d75a334958a06d2723003d0cc18c300..8f2d03bed0cf05741b093ff00475f21b100e1c63 100644
--- a/src/sbbs3/js_global.c
+++ b/src/sbbs3/js_global.c
@@ -72,7 +72,7 @@ static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 			*vp=DOUBLE_TO_JSVAL(ERROR_VALUE);
 			break;
 		case GLOB_PROP_SOCKET_ERRNO_STR:
-			if((js_str=JS_NewStringCopyZ(cx, socket_strerror(socket_errno, err, sizeof(err))))==NULL)
+			if((js_str=JS_NewStringCopyZ(cx, SOCKET_STRERROR(err, sizeof(err))))==NULL)
 				return(JS_FALSE);
 	        *vp = STRING_TO_JSVAL(js_str);
 			break;
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index b29f1c35d6876e1c198783e36eb4546df3544d29..1a1701a614201a5e2129a58a6a0f9e3cde460ebb 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -2674,7 +2674,7 @@ void output_thread(void* arg)
 				lprintf(LOG_NOTICE,"%s connection aborted by peer on send", node);
 			else
 				lprintf(LOG_WARNING,"%s !ERROR %d (%s) sending on socket %d"
-					,node, ERROR_VALUE, socket_strerror(socket_errno, errmsg, sizeof errmsg), sbbs->client_socket);
+					,node, ERROR_VALUE, SOCKET_STRERROR(errmsg, sizeof errmsg), sbbs->client_socket);
 			sbbs->online=false;
 			/* was break; on 4/7/00 */
 			i=buftop-bufbot;	// Pretend we sent it all
diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c
index bc8a3540acccd3dba3fe3b6a39f44aebff84ca77..688396a3b1ce3e99f07d7093370142c01aa8505f 100644
--- a/src/sbbs3/services.c
+++ b/src/sbbs3/services.c
@@ -293,7 +293,7 @@ static int close_socket(SOCKET sock)
 	if(startup!=NULL && startup->socket_open!=NULL)
 		startup->socket_open(startup->cbdata,false);
 	if(result!=0)
-		lprintf(LOG_WARNING,"%04d !ERROR %d closing socket: %s",sock, ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)));
+		lprintf(LOG_WARNING,"%04d !ERROR %d closing socket: %s",sock, ERROR_VALUE, SOCKET_STRERROR(err, sizeof(err)));
 
 	return(result);
 }
@@ -1781,7 +1781,7 @@ static void cleanup(int code)
 	if(WSAInitialized) {
 		char err[128];
 		if(WSACleanup()!=0)
-			lprintf(LOG_ERR,"0000 !WSACleanup ERROR %d: %s",ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)));
+			lprintf(LOG_ERR,"0000 !WSACleanup ERROR %d: %s",ERROR_VALUE, SOCKET_STRERROR(err, sizeof(err)));
 		WSAInitialized = false;
 	}
 #endif
@@ -1829,14 +1829,14 @@ void service_udp_sock_cb(SOCKET sock, void *cbdata)
 	optval=true;
 	if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval,sizeof(optval))!=0) {
 		lprintf(LOG_ERR,"%04d !ERROR %d setting %s socket option: %s"
-			,sock, ERROR_VALUE, serv->protocol, socket_strerror(socket_errno, err, sizeof(err)));
+			,sock, ERROR_VALUE, serv->protocol, SOCKET_STRERROR(err, sizeof(err)));
 		close_socket(sock);
 		return;
 	}
    #ifdef BSD
 	if(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char*)&optval,sizeof(optval))!=0) {
 		lprintf(LOG_ERR,"%04d !ERROR %d setting %s socket option: %s"
-			,sock, ERROR_VALUE, serv->protocol, socket_strerror(socket_errno, err, sizeof(err)));
+			,sock, ERROR_VALUE, serv->protocol, SOCKET_STRERROR(err, sizeof(err)));
 		close_socket(sock);
 		return;
 	}
@@ -2176,7 +2176,7 @@ void services_thread(void* arg)
 					lprintf(LOG_DEBUG,"0000 Services listening interrupted");
 				else
 					lprintf(LOG_WARNING,"0000 !ERROR %d polling sockets: %s"
-						, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+						, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 				continue;
 			}
 			nfdsi = 0;
@@ -2221,7 +2221,7 @@ void services_thread(void* arg)
             		lprintf(LOG_NOTICE,"0000 Services sockets closed");
 				else
 					lprintf(LOG_WARNING,"0000 !ERROR %d selecting sockets: %s"
-						, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+						, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 				continue;
 			}
 
@@ -2253,7 +2253,7 @@ void services_thread(void* arg)
 						if(udp_len<1) {
 							FREE_AND_NULL(udp_buf);
 							lprintf(LOG_WARNING,"%04d %s !ERROR %d recvfrom failed: %s"
-								,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+								,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 							continue;
 						}
 
@@ -2261,7 +2261,7 @@ void services_thread(void* arg)
 							==INVALID_SOCKET) {
 							FREE_AND_NULL(udp_buf);
 							lprintf(LOG_ERR,"%04d %s !ERROR %d opening socket: %s"
-								,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+								,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 							continue;
 						}
 
@@ -2274,7 +2274,7 @@ void services_thread(void* arg)
 							,(char*)&optval,sizeof(optval))!=0) {
 							FREE_AND_NULL(udp_buf);
 							lprintf(LOG_ERR,"%04d %s !ERROR %d setting socket option: %s"
-								,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+								,client_socket, service[i].protocol, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 							close_socket(client_socket);
 							continue;
 						}
@@ -2283,7 +2283,7 @@ void services_thread(void* arg)
 							,(char*)&optval,sizeof(optval))!=0) {
 							FREE_AND_NULL(udp_buf);
 							lprintf(LOG_ERR,"%04d %s !ERROR %d setting socket option: %s"
-								,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+								,client_socket, service[i].protocol, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 							close_socket(client_socket);
 							continue;
 						}
@@ -2296,14 +2296,14 @@ void services_thread(void* arg)
 							/* Failed to re-bind to same port number, use user port */
 							lprintf(LOG_NOTICE,"%04d %s ERROR %d re-binding socket to port %u failed, "
 								"using user port: %s"
-								,client_socket, service[i].protocol, ERROR_VALUE, service[i].port, socket_strerror(socket_errno,error,sizeof(error)));
+								,client_socket, service[i].protocol, ERROR_VALUE, service[i].port, SOCKET_STRERROR(error,sizeof(error)));
 							inet_setaddrport(&addr, 0);
 							result=bind(client_socket, (struct sockaddr *) &addr, addr_len);
 						}
 						if(result!=0) {
 							FREE_AND_NULL(udp_buf);
 							lprintf(LOG_ERR,"%04d %s !ERROR %d re-binding socket to port %u: %s"
-								,client_socket, service[i].protocol, ERROR_VALUE, service[i].port, socket_strerror(socket_errno,error,sizeof(error)));
+								,client_socket, service[i].protocol, ERROR_VALUE, service[i].port, SOCKET_STRERROR(error,sizeof(error)));
 							close_socket(client_socket);
 							continue;
 						}
@@ -2313,7 +2313,7 @@ void services_thread(void* arg)
 							,(struct sockaddr *)&client_addr, client_addr_len)!=0) {
 							FREE_AND_NULL(udp_buf);
 							lprintf(LOG_ERR,"%04d %s !ERROR %d connect failed: %s"
-								,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+								,client_socket, service[i].protocol, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 							close_socket(client_socket);
 							continue;
 						}
@@ -2327,7 +2327,7 @@ void services_thread(void* arg)
 									,service[i].set->socks[j].sock, service[i].protocol);
 							else
 								lprintf(LOG_WARNING,"%04d %s !ERROR %d accepting connection: %s"
-									,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
+									,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, SOCKET_STRERROR(error,sizeof(error)));
 	#ifdef _WIN32
 							if(WSAGetLastError()==WSAENOBUFS)	/* recycle (re-init WinSock) on this error */
 								break;
diff --git a/src/xpdev/ini_file.c b/src/xpdev/ini_file.c
index 6c024da1a8aca54e6a2b1655e655ae5454079a14..d55d95d8810521e8ad29763986e85edc7be2c019 100644
--- a/src/xpdev/ini_file.c
+++ b/src/xpdev/ini_file.c
@@ -2052,13 +2052,13 @@ int iniGetSocketOptions(str_list_t list, const char* section, SOCKET sock
 
 	len=sizeof(type);
 	if((result=getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&type, &len)) != 0) {
-		safe_snprintf(error,errlen,"%d (%s) getting socket type", ERROR_VALUE, socket_strerror(socket_errno,err,sizeof(err)));
+		safe_snprintf(error,errlen,"%d (%s) getting socket type", ERROR_VALUE, SOCKET_STRERROR(err,sizeof(err)));
 		return(result);
 	}
 #ifdef IPPROTO_IPV6
 	len=sizeof(addr);
 	if((result=getsockname(sock, &addr.addr, &len)) != 0) {
-		safe_snprintf(error,errlen,"%d (%s) getting socket name", ERROR_VALUE, socket_strerror(socket_errno,err,sizeof(err)));
+		safe_snprintf(error,errlen,"%d (%s) getting socket name", ERROR_VALUE, SOCKET_STRERROR(err,sizeof(err)));
 		return(result);
 	}
 #endif
@@ -2094,7 +2094,7 @@ int iniGetSocketOptions(str_list_t list, const char* section, SOCKET sock
 
 		if((result=setsockopt(sock,level,option,(const char *)vp,len)) != 0) {
 			safe_snprintf(error,errlen,"%d (%s) setting socket option (%s, %d) to %d"
-				,ERROR_VALUE, socket_strerror(socket_errno,err,sizeof(err)), name, option, value);
+				,ERROR_VALUE, SOCKET_STRERROR(err,sizeof(err)), name, option, value);
 			return(result);
 		}
 	}
diff --git a/src/xpdev/multisock.c b/src/xpdev/multisock.c
index 6a2c1c4d425dafc3d82402c3c85ecff1f47c39b1..bdaacc98b3c47dfb4dc832f378c8d8d0d8d35b8b 100644
--- a/src/xpdev/multisock.c
+++ b/src/xpdev/multisock.c
@@ -156,7 +156,7 @@ bool xpms_add(struct xpms_set *xpms_set, int domain, int type,
 				if(xpms_set->lprintf)
 					xpms_set->lprintf(LOG_WARNING, "%04d !%s ERROR %d listening on port %d: %s"
 						,xpms_set->socks[xpms_set->sock_count].sock, prot, ERROR_VALUE
-						,port, socket_strerror(socket_errno,err,sizeof(err)));
+						,port, SOCKET_STRERROR(err,sizeof(err)));
 				closesocket(xpms_set->socks[xpms_set->sock_count].sock);
 				FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
 				FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
@@ -271,7 +271,7 @@ static bool read_socket(SOCKET sock, char *buffer, size_t len, int (*lprintf)(in
 				buffer[i] = ch;
 
 			} else {
-				lprintf(LOG_WARNING,"%04d multisock read_socket() - failed to read from socket. Got [%d] with error [%s]",sock,rd,socket_strerror(socket_errno,err,sizeof(err)));
+				lprintf(LOG_WARNING,"%04d multisock read_socket() - failed to read from socket. Got [%d] with error [%s]",sock,rd,SOCKET_STRERROR(err,sizeof(err)));
 				return false;
 			}
 
diff --git a/src/xpdev/sockwrap.c b/src/xpdev/sockwrap.c
index aac1e38bd829072fa4e4de9c7654d9476db9f275..d6389300ae2890a5576cbedeb5e3f65eeb4f1924 100644
--- a/src/xpdev/sockwrap.c
+++ b/src/xpdev/sockwrap.c
@@ -573,7 +573,7 @@ int retry_bind(SOCKET s, const struct sockaddr *addr, socklen_t addrlen
 			break;
 		if(lprintf!=NULL)
 			lprintf(i<retries ? LOG_WARNING:LOG_CRIT
-				,"%04d !ERROR %d binding %s socket%s: %s", s, ERROR_VALUE, prot, port_str, socket_strerror(socket_errno, err, sizeof(err)));
+				,"%04d !ERROR %d binding %s socket%s: %s", s, ERROR_VALUE, prot, port_str, SOCKET_STRERROR(err, sizeof(err)));
 		if(i<retries) {
 			if(lprintf!=NULL)
 				lprintf(LOG_WARNING,"%04d Will retry in %u seconds (%u of %u)"
@@ -731,16 +731,6 @@ DLLEXPORT void set_socket_errno(int err)
 #endif
 }
 
-DLLEXPORT int get_socket_errno(void)
-{
-#if defined(_WINSOCKAPI_)
-	int wsa_error = WSAGetLastError();
-	return wsa_error >= WSABASEERR ? wsa_error - WSABASEERR : wsa_error;
-#else
-	return errno;
-#endif
-}
-
 DLLEXPORT int xp_inet_pton(int af, const char *src, void *dst)
 {
 	struct addrinfo hints = {0};
diff --git a/src/xpdev/sockwrap.h b/src/xpdev/sockwrap.h
index 2646f1ad61f8a118a92a97ea702579356e0e02b6..1aaffbde1f3289f230c4f2750739288dba088f64 100644
--- a/src/xpdev/sockwrap.h
+++ b/src/xpdev/sockwrap.h
@@ -175,9 +175,7 @@ union xp_sockaddr {
 #define sa_family_t		ushort
 typedef uint32_t                in_addr_t;
 
-static  int wsa_error;
-#define ERROR_VALUE			((wsa_error=WSAGetLastError())>0 ? wsa_error-WSABASEERR : wsa_error)
-#define socket_errno		WSAGetLastError()
+#define ERROR_VALUE			socket_errno(true) // Deprecated
 #define sendsocket(s,b,l)	send(s,b,l,0)
 typedef ULONG nfds_t;
 /*
@@ -209,7 +207,6 @@ typedef ULONG nfds_t;
 #define closesocket		close
 #define ioctlsocket		ioctl
 #define ERROR_VALUE		errno
-#define socket_errno	errno
 #define sendsocket		write		/* FreeBSD send() is broken */
 
 #ifdef __WATCOMC__
@@ -218,6 +215,19 @@ typedef ULONG nfds_t;
 
 #endif	/* __unix__ */
 
+static inline
+int socket_errno(bool normalize)
+{
+#if defined _WINSOCKAPI_
+	int wsa_error = WSAGetLastError();
+	if(normalize && wsa_error > 0)
+		return wsa_error - WSABASEERR;
+	return wsa_error;
+#else
+	return errno;
+#endif
+}
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -238,8 +248,8 @@ DLLEXPORT uint16_t inet_addrport(union xp_sockaddr *addr);
 DLLEXPORT void inet_setaddrport(union xp_sockaddr *addr, uint16_t port);
 DLLEXPORT bool inet_addrmatch(union xp_sockaddr* addr1, union xp_sockaddr* addr2);
 DLLEXPORT char* socket_strerror(int, char*, size_t);
+#define SOCKET_STRERROR(str, size)	socket_strerror(socket_errno(false), str, size)
 DLLEXPORT void set_socket_errno(int);
-DLLEXPORT int get_socket_errno(void);
 DLLEXPORT int xp_inet_pton(int af, const char *src, void *dst);
 #if defined(_WIN32) // mingw and WinXP's WS2_32.DLL don't have inet_pton():
 	#define inet_pton	xp_inet_pton