Release 980201

Sun Feb  1 13:24:54 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/drive.c]
	Added Device= parameter to drive configuration.

	* [if1632/relay.c]
	Throw() and Catch() now use the correct CATCHBUF layout (untested).

	* [tools/build.c] [include/stackframe.h] [loader/task.c]
	Moved 16-bit stack pointer into thread database.
	Save current %fs while running 16-bit code.

Fri Jan 30 09:25:49 1998  Martin Boehme  <boehme@informatik.mu-luebeck.de>

	* [graphics/mapping.c]
	Made DPtoLP32 and LPtoDP32 respect world transforms.

	* [graphics/path.c] [graphics/painting.c] [if1632/gdi.spec]
	  [include/path.h]
	More path support.

	* [include/gdi.h] [include/windows.h] [objects/dc.c]
	  [relay/gdi32.spec]
	Support for Get/SetArcDirection and Get/SetWorldTransform

	* [windows/hook.c]
	Fixed a bug in HOOK_Map16To32Common.

Thu Jan 29 23:43:18 1998  Douglas Ridgway <ridgway@taiga.gmcl.com>

	* [graphics/metafiledrv/init.c] [objects/metafile.c]
	Documentation for metafile related API calls. Fixed a bug to avoid
	documenting it.

	* [include/windows.h]
	Declaration for LoadImage.

Thu Jan 29 21:44:45 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [graphics/win16drv/*]
	Changes to printing code to enable use of printer fonts with the
	win3.1 postscript driver. Remember to add printer=on to [wine]
	section of wine.conf . You will also need to disable truetype
	fonts from control panel. Winword 6.0 and Write seem to be happy
	with this...

	* [include/bitmap.h]
	Fix Widthbytes for 15bpp displays.

Tue Jan 27 20:54:08 1998  Kristian Nielsen <kristian.nielsen@risoe.dk>

	* [tsx11/*] [include/ts*] [tools/make_X11wrappers]
	Implemented thread-safe X11 wrappers.

Tue Jan 27 13:54:09 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>

	* [windows/queue.c]
	Forgot to convert thdb to thread_id.

	* [misc/registry.c]
	Sped up Windows 95 registry reading. Changed code to traverse
	registry as a tree rather than read in all possible keys
	(including dead ones). 

Tue Jan 27 12:46:09 1998  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][Makefile.in][scheduler/thread.c]
	  [libtest/hello5.c]
	Don't exit() on failed to load referenced dlls.
	Fixed static tls allocation for multiple threads.
	WINELIB should now be able to load PE dlls. A sample
	winelib program, that dynamically loads a internal dll
	is included.

	* [graphics/ddraw.c][include/ddraw.h][include/d3d.h]
	Cleaned up and enhanced further. Added several DirectX5
	interface definitions and DirectSurface3 implementation.
	Stubs for D3D (NOT coming soon, just there so it fails safely).

	* [multimedia/dsound.c][include/dsound.h]
	Actually works now for a lot of cases. Some DirectX5 stuff
	added. Still lacking several features.

	* [windows/dinput.c][include/dinput.h]
	Started implementing DirectInput. Doesn't work yet, don't 
	know why.

	* [if1632/thunk.c][misc/callbacks.c]
	  [win32/kernel.c][include/callbacks.h]
	Added WOWCallback16Ex, WOWHandle32.

	* [misc/cpu.c]
	Fixed GetSystemInfo, IsProcessorFeaturePresent.

	* [multimedia/joystick.c][multimedia/time.c]
	Several fixes. Small hack to get timerevents in timeGetTime() loops.

Tue Jan 20 11:26:27 1998  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [configure.in]
	Fixed check for union semun on FreeBSD systems.

Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>

	* [misc/ole2nls.c] [programs/progman/Sw.rc] [programs/winhelp/Sw.rc]
	  [resources/sysres_Sw.rc]
	Added/updated Swedish language support.

Sun Jan 18 18:49:01 1998  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [misc/winsock.c] [misc/winsock_dns.c] [windows/event.c]
	  [windows/win.c] [windows/dce.c] [windows/winpos.c]
	Bug fixes.

Sun Jan 18 12:45:23 1997  Andreas Mohr <100.30936@germany.net>

	* [msdos/int25.c] [msdos/int26.c]
        Implemented "native" absolute disk read/write access.

	* [msdos/int13.c] [msdos/ioports.c]
	Enhanced GET DRIVE PARAMETERS (int13 AH=08).

	* [graphics/win16drv/prtdrv.c] [if1632/gdi.spec]
	Fixed typos, implemented dmEnumDFonts,
	Started implementation of dmRealizeObject.

	* [if1632/compobj.spec] [ole/compobj.c] [relay32/ole32.spec]
	Stubs CoCreateInstance, CoFreeUnusedLibraries, implemented
	CoFileTimeNow.

	* [if1632/kernel.spec] [include/windows.h] [memory/global.c]
	  [memory/string.c] [misc/kernel.c] [misc/Makefile.in]
	  [misc/toolhelp.c] [msdos/int21.c]
	Implemented GlobalHandleNoRIP, GetFreeMemInfo, DebugFillBuffer, 
	stubs GetSetKernelDOSProc, DiagQuery, DiagOutput, ToolHelpHook
	(Undocumented Windows).

	* [if1632/user.spec] [if1632/win32s16.spec] [misc/win32s16.c]
	Misc stubs.

	* [if1632/winaspi.spec] [misc/aspi.c]
	Implemented GetASPIDLLVersion.

	* [if1632/wprocs.spec] [msdos/int20.c] [msdos/Makefile.in]
	Added handler for Int 0x20 (terminate program, _very_ old-fashioned).

	* [misc/w32scomb.c]
	Implemented Get16DLLAddress() partially
	(big thanks to Marcus and Alexandre).

	* [relay32/Makefile.in] [relay32/builtin32.c] [relay32/dplay.spec]
	Added built-in DPLAY.DLL.

	* [relay32/winmm.spec] [multimedia/joystick.c]
	Added joySetThreshold.

	* [misc/windebug.c]
	Added WinNotify.

	* [win32/console.c]
	Stubs CreateConsoleScreenBuffer, SetConsoleActiveScreenBuffer,
	WriteConsoleOutput32A.

	* [windows/user.c]
	Stub SetEventHook.

Sat Jan 17 19:30:35 1998  Matthew Toseland  <Paul.Toseland@btinternet.com>

	* [windows/painting.c]
	Fixed broken restore-to-maximized.

Mon Jan 12 21:25:32 1998  Perceval - Marc Huguet Puig <mhp@tinet.fut.es>

	* [documentation/wine.man] [include/options.h]
	  [misc/main.c] [ole/ole2nls.c] [resources/sysres.c]
	  [resources/sysres_Ca.rc] [resources/Makefile.in]
	Added language catalan. (Afegit l'idioma catalĂ ).
diff --git a/misc/winsock.c b/misc/winsock.c
index 88c740c..ff3dba3 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -4,6 +4,10 @@
  * 
  * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
  *
+ * NOTE: If you make any changes to fix a particular app, make sure 
+ * they don't break something else like Netscape or telnet and ftp 
+ * clients and servers (www.winsite.com got a lot of those).
+ *
  */
  
 #include <stdio.h>
@@ -26,6 +30,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <netdb.h>
@@ -82,8 +87,8 @@
          SO_LINGER, SO_OOBINLINE, SO_SNDBUF, SO_RCVBUF, SO_ERROR, SO_TYPE,
 	 SO_LINGER };
 
-static int _check_ws(LPWSINFO pwsi, ws_socket* pws);
-static int _check_buffer(LPWSINFO pwsi, int size);
+static int   _check_ws(LPWSINFO pwsi, ws_socket* pws);
+static char* _check_buffer(LPWSINFO pwsi, int size);
 
 extern void EVENT_AddIO( int fd, unsigned flag );
 extern void EVENT_DeleteIO( int fd, unsigned flag );
@@ -147,6 +152,23 @@
     return NULL;
 }
 
+static int wsi_strtolo(LPWSINFO pwsi, const char* name, const char* opt)
+{
+    /* Stuff a lowercase copy of the string into the local buffer */
+
+    int i = strlen(name) + 2;
+    char* p = _check_buffer(pwsi, i + ((opt)?strlen(opt):0));
+
+    if( p )
+    {
+	do *p++ = tolower(*name); while(*name++);
+	i = (p - (char*)(pwsi->buffer));
+	if( opt ) do *p++ = tolower(*opt); while(*opt++);
+	return i;
+    }
+    return 0;
+}
+
 static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, void* wsfds, int* highfd, BOOL32 b32 )
 {
     /* translate Winsock fd set into local fd set */
@@ -159,7 +181,8 @@
 	int i, count;
 
 	FD_ZERO(fds);
-	count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
+	count = b32 ? wsfds32->fd_count : wsfds16->fd_count;
+
 	for( i = 0; i < count; i++ )
 	{
 	     pws = (b32) ? (ws_socket*)WS_HANDLE2PTR(wsfds32->fd_array[i])
@@ -170,10 +193,6 @@
 		    FD_SET(pws->fd, fds);
 	     }
 	}
-	if (b32)
-	     wsfds32->fd_count = 0;
-	else
-	     wsfds16->fd_count = 0;
 #undef wsfds32
 #undef wsfds16
 	return fds;
@@ -208,20 +227,22 @@
 	{
 	    ws_socket *pws = (b32) ? (ws_socket*)WS_HANDLE2PTR(wsfds32->fd_array[i])
 				   : (ws_socket*)WS_HANDLE2PTR(wsfds16->fd_array[i]);
-	    int fd = pws->fd;
-
-	    if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
+	    if( _check_ws(pwsi, pws) )
 	    {
-		if ( exceptfds && sock_error_p(fd) )
+		int fd = pws->fd;
+
+		if( FD_ISSET(fd, fds) )
 		{
-		    FD_SET(fd, exceptfds);
-		    num_err++;
+		    if ( exceptfds && sock_error_p(fd) )
+		    {
+			FD_SET(fd, exceptfds);
+			num_err++;
+		    }
+		    else if( b32 )
+			     wsfds32->fd_array[j++] = wsfds32->fd_array[i];
+			 else
+			     wsfds16->fd_array[j++] = wsfds16->fd_array[i];
 		}
-		else
-		    if( b32 )
-			wsfds32->fd_array[j++] = wsfds32->fd_array[i];
-		    else
-			wsfds16->fd_array[j++] = wsfds16->fd_array[i];
 	    }
 	}
 
@@ -278,7 +299,7 @@
                         #else
                                 "Unknown",
                         #endif
-			   WS_MAX_SOCKETS_PER_THREAD,
+			   WS_MAX_SOCKETS_PER_PROCESS,
 			   WS_MAX_UDP_DATAGRAM, (SEGPTR)NULL };
     HTASK16             tid = GetCurrentTask();
     LPWSINFO            pwsi;
@@ -314,12 +335,12 @@
 	{
 	    int i = 0;
 	    pwsi->tid = tid;
-	    for( i = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++ )
+	    for( i = 0; i < WS_MAX_SOCKETS_PER_PROCESS; i++ )
 	    {
 		pwsi->sock[i].fd = -1; 
 		pwsi->sock[i].flags = i + 1; 
 	    }
-	    pwsi->sock[WS_MAX_SOCKETS_PER_THREAD - 1].flags = -1;
+	    pwsi->sock[WS_MAX_SOCKETS_PER_PROCESS - 1].flags = -1;
 	}
 	else return WSASYSNOTREADY;
 
@@ -400,7 +421,7 @@
  *	  dprintf_winsock(stddeb,"\thave %i outstanding async ops!\n", pwsi->num_async_rq );
  */
 
-    for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++)
+    for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_PROCESS; i++)
 	if( pwsi->sock[i].fd != -1 )
 	{
 	    if( pwsi->sock[i].psop )
@@ -485,13 +506,13 @@
     return 0;
 }
 
-int _check_buffer(LPWSINFO pwsi, int size)
+char* _check_buffer(LPWSINFO pwsi, int size)
 {
-    if( pwsi->buffer && pwsi->buflen >= size ) return 1;
+    if( pwsi->buffer && pwsi->buflen >= size ) return pwsi->buffer;
     else SEGPTR_FREE(pwsi->buffer);
 
     pwsi->buffer = (char*)SEGPTR_ALLOC((pwsi->buflen = size)); 
-    return (pwsi->buffer != NULL);
+    return pwsi->buffer;
 }
 
 /* ----------------------------------- i/o APIs */
@@ -558,9 +579,9 @@
 
     dprintf_winsock(stddeb, "WS_BIND(%08x): socket %04x, ptr %8x, length %d\n", 
 			   (unsigned)pwsi, s, (int) name, namelen);
-/* #if DEBUG_SOCKADDR */
+#if DEBUG_SOCKADDR
     dump_sockaddr(name);
-/* #endif */
+#endif
 
     if ( _check_ws(pwsi, pws) )
       if ( namelen >= sizeof(*name) ) 
@@ -936,7 +957,7 @@
 		if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
 	    }
 	    pws->flags |= WS_FD_LISTENING;
-	    pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECTED); /* just in case */
+	    pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT | WS_FD_CONNECTED); /* just in case */
 	    return 0;
 	}
 	pwsi->err = wsaErrno();
@@ -1065,42 +1086,44 @@
 	p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd, b32);
 	p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd, b32);
 
-	if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) >= 0 )
+	if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) > 0 )
 	{
-	    if( highfd )
-	    {
-		fd_set_export(pwsi, &readfds, p_except, ws_readfds, b32);
-		fd_set_export(pwsi, &writefds, p_except, ws_writefds, b32);
+	    fd_set_export(pwsi, &readfds, p_except, ws_readfds, b32);
+	    fd_set_export(pwsi, &writefds, p_except, ws_writefds, b32);
 
-		if (p_except && ws_exceptfds)
-		{
+	    if (p_except && ws_exceptfds)
+	    {
 #define wsfds16 ((ws_fd_set16*)ws_exceptfds)
 #define wsfds32 ((ws_fd_set32*)ws_exceptfds)
-		    int i, j, count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
+		int i, j, count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
 
-		    for (i = j = 0; i < count; i++)
+		for (i = j = 0; i < count; i++)
+		{
+		    ws_socket *pws = (b32) ? (ws_socket *)WS_HANDLE2PTR(wsfds32->fd_array[i])
+					   : (ws_socket *)WS_HANDLE2PTR(wsfds16->fd_array[i]);
+		    if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
 		    {
-			ws_socket *pws = (b32) ? (ws_socket *)WS_HANDLE2PTR(wsfds32->fd_array[i])
-					       : (ws_socket *)WS_HANDLE2PTR(wsfds16->fd_array[i]);
-			if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
-			{
-			    if( b32 )
+			if( b32 )
 				wsfds32->fd_array[j++] = wsfds32->fd_array[i];
-			    else
+			else
 				wsfds16->fd_array[j++] = wsfds16->fd_array[i];
-			}
 		    }
-		    if( b32 )
-			wsfds32->fd_count = j;
-		    else
-			wsfds16->fd_count = j;
+		}
+		if( b32 )
+		    wsfds32->fd_count = j;
+		else
+		    wsfds16->fd_count = j;
 #undef wsfds32
 #undef wsfds16
-		}
 	    }
 	    return highfd; 
 	}
-        pwsi->err = wsaErrno();
+	if( ws_readfds ) ((ws_fd_set32*)ws_readfds)->fd_count = 0;
+	if( ws_writefds ) ((ws_fd_set32*)ws_writefds)->fd_count = 0;
+	if( ws_exceptfds ) ((ws_fd_set32*)ws_exceptfds)->fd_count = 0;
+
+        if( highfd == 0 ) return 0;
+	pwsi->err = wsaErrno();
     } 
     return SOCKET_ERROR;
 }
@@ -1253,15 +1276,24 @@
 			if( pws->flags & (WS_FD_READ | WS_FD_CLOSE) )
 			    EVENT_DeleteIO( pws->fd, EVENT_IO_READ );
 			pws->flags &= ~(WS_FD_READ | WS_FD_CLOSE);
+#ifdef SHUT_RD
+			how = SHUT_RD;
+#endif
 			break;
 
 		case 1: /* drop sends */
 			if( pws->flags & WS_FD_WRITE )
 			    EVENT_DeleteIO( pws->fd, EVENT_IO_WRITE );
 			pws->flags &= ~WS_FD_WRITE;
+#ifdef SHUT_WR
+			how = SHUT_WR;
+#endif
 			break;
 
 		case 2: /* drop all */
+#ifdef SHUT_RDWR
+			how = SHUT_RDWR;
+#endif
 		default:
 			WSAAsyncSelect32( s, 0, 0, 0 );
 			break;
@@ -1342,9 +1374,13 @@
     {
         ws_socket*      pnew = wsi_alloc_socket(pwsi, sock);
 
-	dprintf_winsock(stddeb,"\tcreated %04x (handle %i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
+	dprintf_winsock(stddeb,"\tcreated %i (handle %04x)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
 
-        if( pnew ) return (SOCKET16)WS_PTR2HANDLE(pnew);
+        if( pnew ) 
+	{
+	    pnew->flags |= WS_FD_INACTIVE;
+	    return (SOCKET16)WS_PTR2HANDLE(pnew);
+	}
 	
         close(sock);
         pwsi->err = WSAENOBUFS;
@@ -1375,7 +1411,8 @@
  *
  * IMPORTANT: 16-bit API structures have SEGPTR pointers inside them.
  * Also, we have to use wsock32 stubs to convert structures and
- * error codes from Unix to WSA, hence no direct mapping in if1632/wsock32.spec.
+ * error codes from Unix to WSA, hence there is no direct mapping in 
+ * the relay32/wsock32.spec.
  */
 
 static char*	NULL_STRING = "NULL";
@@ -1530,11 +1567,15 @@
     if( pwsi )
     {
 	struct servent*     serv;
-	if( (serv = getservbyname(name, proto)) != NULL )
-	    if( WS_dup_se(pwsi, serv, dup_flag) )
-		return (struct WIN_servent*)(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	int i = wsi_strtolo( pwsi, name, proto );
+
+	if( i )
+	    if( (serv = getservbyname(pwsi->buffer, pwsi->buffer + i)) != NULL )
+		if( WS_dup_se(pwsi, serv, dup_flag) )
+		    return (struct WIN_servent*)(pwsi->buffer);
+		else pwsi->err = WSAENOBUFS;
+	    else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	else pwsi->err = WSAENOBUFS;
     }
     return NULL;
 }
@@ -1566,11 +1607,15 @@
     if( pwsi )
     {
 	struct servent*     serv;
-	if( (serv = getservbyport(port, proto)) != NULL )
-	    if( WS_dup_se(pwsi, serv, dup_flag) )
-		return (struct WIN_servent*)(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	int i = wsi_strtolo( pwsi, proto, NULL );
+
+	if( i )
+	    if( (serv = getservbyport(port, pwsi->buffer)) != NULL )
+		if( WS_dup_se(pwsi, serv, dup_flag) )
+		    return (struct WIN_servent*)(pwsi->buffer);
+		else pwsi->err = WSAENOBUFS;
+	    else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	else pwsi->err = WSAENOBUFS;
     }
     return NULL;
 }
@@ -1781,8 +1826,13 @@
                    (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
 
   if( pwsi )
-    return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
-                            proto, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
+  {
+      int i = wsi_strtolo( pwsi, name, proto );
+
+      if( i )
+          return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, pwsi->buffer, 0,
+                    pwsi->buffer + i, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
+  }
   return 0;
 }
 
@@ -1797,8 +1847,13 @@
   dprintf_winsock(stddeb, "WS_AsyncGetServByName32(%08x): hwnd %04x, msg %08x, name %s, proto %s\n",
            (unsigned)pwsi, (HWND16)hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
   if( pwsi )
-    return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
-                            proto, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME | WSMSG_ASYNC_WIN32);
+  {
+      int i = wsi_strtolo( pwsi, name, proto );
+
+      if( i )
+          return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, pwsi->buffer, 0,
+                 pwsi->buffer + i, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME | WSMSG_ASYNC_WIN32);
+  }
   return 0;
 }
 
@@ -1815,8 +1870,13 @@
                            (unsigned)pwsi, hWnd, uMsg, port, (proto)?proto:NULL_STRING );
 
   if( pwsi )
-      return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
-                              NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
+  {
+      int i = wsi_strtolo( pwsi, proto, NULL );
+
+      if( i )
+	  return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, pwsi->buffer, 0,
+		NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
+  }
   return 0;
 }
 
@@ -1832,8 +1892,13 @@
                            (unsigned)pwsi, (HWND16)hWnd, uMsg, port, (proto)?proto:NULL_STRING );
 
   if( pwsi )
-      return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
-             NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT | WSMSG_ASYNC_WIN32);
+  {
+      int i = wsi_strtolo( pwsi, proto, NULL );
+
+      if( i )
+	  return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, pwsi->buffer, 0,
+		 NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT | WSMSG_ASYNC_WIN32);
+  }
   return 0;
 }
 
@@ -1875,10 +1940,12 @@
 
 static ws_select_op* __ws_select_list = NULL;
 
-BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] )
+BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, 
+			 fd_set pending_set[3], fd_set event_set[3] )
 {
     /* This function is called by the event dispatcher
-     * with io_set containing the result of select() */
+     * with the pending_set[] containing the result of select() and
+     * the event_set[] containing all fd that are being watched */
 
     ws_select_op*	psop = __ws_select_list;
     BOOL32		bPost = FALSE;
@@ -1894,9 +1961,9 @@
 	int		r, w, e;
 
 	w = 0;
-	if( (r = FD_ISSET( fd, &io_set[EVENT_IO_READ] )) ||
-	    (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] )) ||
-	    (e = FD_ISSET( fd, &io_set[EVENT_IO_EXCEPT] )) )
+	if( (r = FD_ISSET( fd, &pending_set[EVENT_IO_READ] )) ||
+	    (w = FD_ISSET( fd, &pending_set[EVENT_IO_WRITE] )) ||
+	    (e = FD_ISSET( fd, &pending_set[EVENT_IO_EXCEPT] )) )
 	{
 	    /* This code removes WS_FD flags on one-shot events (WS_FD_CLOSE, 
 	     * WS_FD_CONNECT), otherwise it clears descriptors in the io_set.
@@ -1918,10 +1985,10 @@
 		/* WS_FD_ACCEPT is valid only if the socket is in the
 		 * listening state */
 
-		FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+		FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 		if( r )
 		{
-		    FD_CLR( fd, &io_set[EVENT_IO_READ] ); /* reenabled by the next accept() */
+		    FD_CLR( fd, &event_set[EVENT_IO_READ] ); /* reenabled by the next accept() */
 		    dwEvent = WSAMAKESELECTREPLY( WS_FD_ACCEPT, 0 );
 		    bPost = TRUE;
 		} 
@@ -1931,22 +1998,27 @@
 	    {
 		/* connecting socket */
 
-		if( w || (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] )) )
+		if( w || (w = FD_ISSET( fd, &pending_set[EVENT_IO_WRITE] )) )
 		{
-		    /* ready to write means that socket is connected */
+		    /* ready to write means that socket is connected 
+		     *
+		     * FIXME: Netscape calls AsyncSelect( s, ... WS_FD_CONNECT .. )
+		     * right after s = socket() and somehow "s" becomes writeable 
+		     * before it goes through connect()!?!?
+		     */
 
 		    psop->pws->flags |= WS_FD_CONNECTED;
 		    psop->pws->flags &= ~(WS_FD_CONNECT | WS_FD_INACTIVE);
 		    dwEvent = WSAMAKESELECTREPLY( WS_FD_CONNECT, 0 );
 
 		    if( flags & (WS_FD_READ | WS_FD_CLOSE))
-			FD_SET( fd, &io_set[EVENT_IO_READ] );
+			FD_SET( fd, &event_set[EVENT_IO_READ] );
 		    else 
-			FD_CLR( fd, &io_set[EVENT_IO_READ] );
+			FD_CLR( fd, &event_set[EVENT_IO_READ] );
 		    if( flags & WS_FD_WRITE ) 
-			FD_SET( fd, &io_set[EVENT_IO_WRITE] );
+			FD_SET( fd, &event_set[EVENT_IO_WRITE] );
 		    else 
-			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+			FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 		    bPost = TRUE;
 		}
 		else if( r )
@@ -1959,16 +2031,14 @@
 			bPost = TRUE;
 		    }
 		}
-		/* otherwise bPost stays FALSE */
+		/* otherwise bPost stays FALSE, should probably clear event_set  */
 	    }
 	    else 
 	    {
-		/* connected socket --
-		 * removed WS_FD_OOB code for now.
-		 */
+		/* connected socket, no WS_FD_OOB code for now. */
 
 		if( flags & WS_FD_WRITE &&
-		   (w || (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] ))) )
+		   (w || (w = FD_ISSET( fd, &pending_set[EVENT_IO_WRITE] ))) )
 		{
 		    /* this will be reenabled when send() or sendto() fail with
 		     * WSAEWOULDBLOCK */
@@ -1978,7 +2048,7 @@
 		    {
 			dprintf_winsock(stddeb, "\t    hwnd %04x - %04x, %08x\n",
                                 psop->hWnd, psop->uMsg, (unsigned)MAKELONG(WS_FD_WRITE, 0) );
-			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+			FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 			num_posted++;
 		    }
 		}
@@ -2000,7 +2070,7 @@
 		    {
 			/* got pending data, will be reenabled by recv() or recvfrom() */
 
-			FD_CLR( fd, &io_set[EVENT_IO_READ] );
+			FD_CLR( fd, &event_set[EVENT_IO_READ] );
 			dwEvent = WSAMAKESELECTREPLY( WS_FD_READ, 0 );
 		    }
 		    else
@@ -2028,8 +2098,8 @@
 			/* this is it, this socket is closed */
 
 			psop->pws->flags &= ~(WS_FD_READ | WS_FD_CLOSE | WS_FD_WRITE);
-			FD_CLR( fd, &io_set[EVENT_IO_READ] );
-			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+			FD_CLR( fd, &event_set[EVENT_IO_READ] );
+			FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 
 			if( *max_fd == (fd + 1) ) (*max_fd)--;
 		    }
@@ -2107,7 +2177,7 @@
 		psop->uMsg = uMsg;
 
 		pws->psop = psop;
-		pws->flags |= (0x0000FFFF &lEvent);
+		pws->flags |= (0x0000FFFF & lEvent);
 		getsockopt(pws->fd, SOL_SOCKET, SO_TYPE, &sock_type, &bytes);
 		if( sock_type == SOCK_RAW ) pws->flags |= WS_FD_RAW;
 
@@ -2143,7 +2213,7 @@
 {
   int i = set->fd_count;
   
-  dprintf_winsock(stddeb, "__WSAFDIsSet16(%d,%8lx)\n", s,(unsigned long)set);
+  dprintf_winsock(stddeb, "__WSAFDIsSet16(%d,%8lx(%i))\n", s,(unsigned long)set, i);
     
   while (i--)
       if (set->fd_array[i] == s) return 1;
@@ -2157,7 +2227,7 @@
 {
   int i = set->fd_count;
 
-  dprintf_winsock(stddeb, "__WSAFDIsSet32(%d,%8lx)\n", s,(unsigned long)set);
+  dprintf_winsock(stddeb, "__WSAFDIsSet32(%d,%8lx(%i))\n", s,(unsigned long)set, i);
 
   while (i--)
       if (set->fd_array[i] == s) return 1;
@@ -2171,7 +2241,7 @@
 {
   /* By default WinSock should set all its sockets to non-blocking mode
    * and poll in PeekMessage loop when processing "blocking" ones. This 
-   * function is supposed to tell if program is in this loop. Our 
+   * function is supposed to tell if the program is in this loop. Our 
    * blocking calls are truly blocking so we always return FALSE.
    *
    * Note: It is allowed to call this function without prior WSAStartup().
@@ -2332,7 +2402,7 @@
  *
  * TODO: Merge WS_dup_..() stuff into one function that
  * would operate with a generic structure containing internal
- * pointers (via some sort of a template).
+ * pointers (via a template of some kind).
  */
 
 static int list_size(char** l, int item_size)
@@ -2378,7 +2448,7 @@
 
 int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag)
 {
-   /* Duplicate hostent structure and flatten data (with its pointers)
+   /* Convert hostent structure into ws_hostent so that the data fits 
     * into pwsi->buffer. Internal pointers can be linear, SEGPTR, or 
     * relative to pwsi->buffer depending on "flag" value. Returns size
     * of the data copied (also in the pwsi->buflen).
@@ -2479,7 +2549,7 @@
      p = pwsi->buffer;
      p_base = (flag & WS_DUP_OFFSET) ? NULL 
 				     : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
-     p += (flag & WS_DUP_NATIVE)? sizeof(struct servent) : sizeof(struct ws_servent);
+     p += sizeof(struct ws_servent);
      p_name = p;
      strcpy(p, p_se->s_name); p += strlen(p) + 1;
      p_proto = p;