mswsock.dll patch - Add simple TransmitFile functionality [1/2]

Łukasz Chróst lukost at gmail.com
Mon Jun 26 08:44:03 CDT 2006


what has been done:
 - removed stubbed TransmitFile
 - created some service functions for sockets inside  mswsock.dll
 - added required headers (patch includes some more than needed but most
of them are used in future version)
 - defined USE_WS_XXX flag for make
 - added non-overlapped version of TransmitFile

TODO (next version):
  - overlapped version of TransmitFile (there is a lot of code to create
as my current overlapped TransmitFile resides inside ws2_32.dll and uses
it's service functions)
  - remove unnecessary TRACE's

--
Łukasz Chróst

-------------- next part --------------
===================================================================
RCS file: /home/wine/wine/dlls/mswsock/Makefile.in,v
retrieving revision 1.3
diff -u -r1.3 Makefile.in
--- dlls/mswsock/Makefile.in	9 May 2005 14:42:33 -0000	1.3
+++ dlls/mswsock/Makefile.in	25 Jun 2006 22:31:28 -0000
@@ -1,16 +1,20 @@
+EXTRADEFS = -DUSE_WS_PREFIX
 TOPSRCDIR = @top_srcdir@
 TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = mswsock.dll
 IMPORTLIB = libmswsock.$(IMPLIBEXT)
-IMPORTS   = ws2_32 iphlpapi kernel32
+IMPORTS   = ws2_32 iphlpapi kernel32 ntdll
+
 
 C_SRCS = \
 	mswsock.c
 
 RC_SRCS = version.rc
 
+SUBDIRS = tests
+
 @MAKE_DLL_RULES@
 
 ### Dependencies:
Index: dlls/mswsock/mswsock.c
===================================================================
RCS file: /home/wine/wine/dlls/mswsock/mswsock.c,v
retrieving revision 1.4
diff -u -r1.4 mswsock.c
--- dlls/mswsock/mswsock.c	23 May 2006 12:48:20 -0000	1.4
+++ dlls/mswsock/mswsock.c	26 Jun 2006 12:55:24 -0000
@@ -19,18 +19,349 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
 #include <stdarg.h>
-
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_IPC_H
+# include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include <sys/sockio.h>
+#endif
+
+#if defined(__EMX__)
+# include <sys/so_ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_MSG_H
+# include <sys/msg.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+#include <sys/errno.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#endif
+#ifdef HAVE_RESOLV_H
+# include <resolv.h>
+#endif
+#ifdef HAVE_NET_IF_H
+# include <net/if.h>
+#endif
+
+#ifdef HAVE_NETIPX_IPX_H
+# include <netipx/ipx.h>
+# define HAVE_IPX
+#elif defined(HAVE_LINUX_IPX_H)
+# ifdef HAVE_ASM_TYPES_H
+#  include <asm/types.h>
+# endif
+# include <linux/ipx.h>
+# define HAVE_IPX
+#endif
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+#ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "winnls.h"
 #include "winsock2.h"
 #include "mswsock.h"
-
+#include "ws2tcpip.h"
+#include "ws2spi.h"
+#include "wsipx.h"
+#include "winnt.h"
+#include "iphlpapi.h"
+#include "thread.h"
+#include "wine/server.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
+
+#ifdef HAVE_IPX
+# include "wsnwlink.h"
+#endif
+
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+# define sipx_network    sipx_addr.x_net
+# define sipx_node       sipx_addr.x_host.c_host
+#endif  /* __FreeBSD__ */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ~0UL
+#endif
+
+/* ************************************************************************************************ */
+/* Handle validation against INVALID_HANDLE_VALUE */
+#define HANDLE_VALID(x) (!(x==INVALID_HANDLE_VALUE))
+
+/* free memory and set pointer to NULL */
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) {if(x) {free(x); x=NULL;}}
+#endif
+
+/* CloseHandle and set it to INVALID_HANDLE_VALUE  */
+#ifndef SAFE_HRELEASE
+#define SAFE_HRELEASE(x) {if(HANDLE_VALID(x)) {CloseHandle(x); x=INVALID_HANDLE_VALUE;}}
+#endif
+/* ************************************************************************************************ */
+
+#define FILE_DATA_BUFFER_LENGTH 1024
+
+/* HANDLE<->SOCKET conversion (SOCKET is UINT_PTR). */
+#define SOCKET2HANDLE(s) ((HANDLE)(s))
+#define HANDLE2SOCKET(h) ((SOCKET)(h))
+
+#ifdef SO_SNDTIMEO
+#define GET_SNDTIMEO(fd) get_rcvsnd_timeo( (fd), SO_SNDTIMEO)
+#else
+#define GET_SNDTIMEO(fd) (-1)
+#endif
 
+/* ************************************************************************************************ */
 WINE_DEFAULT_DEBUG_CHANNEL(mswsock);
 
+
+/* ************************************************************************************************ *
+ * Async IO declarations
+/* ************************************************************************************************ */
+typedef struct TransmitFile_datainfo
+{
+    HANDLE                              hFile;
+		int																	fd;
+		unsigned long 											filelen;
+		size_t															junklen;
+} TransmitFile_datainfo;
+
+
+
+/* ************************************************************************************************ */
+inline static DWORD NtStatusToWSAError( const DWORD status )
+{
+    /* We only need to cover the status codes set by server async request handling */
+    DWORD wserr;
+    switch ( status )
+    {
+    case STATUS_SUCCESS:              wserr = 0;                     break;
+    case STATUS_PENDING:              wserr = WSA_IO_PENDING;        break;
+    case STATUS_INVALID_HANDLE:       wserr = WSAENOTSOCK;           break;  /* WSAEBADF ? */
+    case STATUS_INVALID_PARAMETER:    wserr = WSAEINVAL;             break;
+    case STATUS_PIPE_DISCONNECTED:    wserr = WSAESHUTDOWN;          break;
+    case STATUS_CANCELLED:            wserr = WSA_OPERATION_ABORTED; break;
+    case STATUS_TIMEOUT:              wserr = WSAETIMEDOUT;          break;
+    case STATUS_NO_MEMORY:            wserr = WSAEFAULT;             break;
+    default:
+        if ( status >= WSABASEERR && status <= WSABASEERR+1004 )
+            /* It is not a NT status code but a winsock error */
+            wserr = status;
+        else
+        {
+            wserr = RtlNtStatusToDosError( status );
+            FIXME( "Status code %08lx converted to DOS error code %lx\n", status, wserr );
+        }
+    }
+    return wserr;
+}
+
+/* ************************************************************************************************ */
+/* forward declarations... */
+UINT wsaErrno(void);
+
+/* ************************************************************************************************ */
+/* set last error code from NT status without mapping WSA errors */
+inline static unsigned int set_error( unsigned int err )
+{
+    if (err)
+    {
+        err = NtStatusToWSAError( err );
+        SetLastError( err );
+    }
+    return err;
+}
+
+/* ************************************************************************************************ */
+/* Get fd from socket via server call */
+inline static int get_sock_fd( SOCKET s, DWORD access, int *flags )
+{
+    int fd;
+    if (set_error( wine_server_handle_to_fd( SOCKET2HANDLE(s), access, &fd, flags ) ))
+        return -1;
+    return fd;
+}
+
+/* ************************************************************************************************ */
+/* release previous */
+inline static void release_sock_fd( SOCKET s, int fd )
+{
+    wine_server_release_fd( SOCKET2HANDLE(s), fd );
+}
+
+
+/* ************************************************************************************************ */
+/* Utility: get the SO_RCVTIMEO or SO_SNDTIMEO socket option
+ * from an fd and return the value converted to milli seconds
+ * or -1 if there is an infinite time out */
+static inline int get_rcvsnd_timeo( int fd, int optname)
+{
+  struct timeval tv;
+  unsigned int len = sizeof(tv);
+  int ret = getsockopt(fd, SOL_SOCKET, optname, &tv, &len);
+  if( ret >= 0)
+      ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+  if( ret <= 0 ) /* tv == {0,0} means infinite time out */
+      return -1;
+  return ret;
+}
+
+static inline void ws_sockaddr_free(const struct sockaddr* uaddr, const struct WS_sockaddr* wsaddr)
+{
+    if (uaddr!=(const struct sockaddr*)wsaddr)
+        HeapFree(GetProcessHeap(), 0, (void *)uaddr);
+}
+/* ************************************************************************************************ */
+/* utility: given an fd, will block until one of the events occurs */
+static inline int do_block( int fd, int events, int timeout )
+{
+  struct pollfd pfd;
+  int ret;
+
+  pfd.fd = fd;
+  pfd.events = events;
+
+  while ((ret = poll(&pfd, 1, timeout)) < 0)
+  {
+      if (errno != EINTR)
+          return -1;
+  }
+  if( ret == 0 )
+      return 0;
+  return pfd.revents;
+}
+
+/* ************************************************************************************************ */
+static void _enable_event( HANDLE s, unsigned int event,
+                           unsigned int sstate, unsigned int cstate )
+{
+    SERVER_START_REQ( enable_socket_event )
+    {
+        req->handle = s;
+        req->mask   = event;
+        req->sstate = sstate;
+        req->cstate = cstate;
+        wine_server_call( req );
+    }
+    SERVER_END_REQ;
+}
+
+/* ************************************************************************************************ */
+static int _is_blocking(SOCKET s)
+{
+    int ret;
+    SERVER_START_REQ( get_socket_event )
+    {
+        req->handle  = SOCKET2HANDLE(s);
+        req->service = FALSE;
+        req->c_event = 0;
+        wine_server_call( req );
+        ret = (reply->state & FD_WINE_NONBLOCKING) == 0;
+    }
+    SERVER_END_REQ;
+    return ret;
+}
+
+
+/* ************************************************************************************************ *
+ *             MWS2_send                (INTERNAL)
+ *
+ * Workhorse for both synchronous and asynchronous send() operations.
+ */
+static int MWS2_send( int fd, struct iovec* iov, int count, DWORD dwFlags )
+{
+    struct msghdr hdr;
+    int n = -1;
+	
+	TRACE("fd: %d, iovec: %p, count: %d, dwFlags: %ld\n",
+			fd, iov, count, dwFlags);
+
+	memset(&hdr, 0, sizeof (struct msghdr));
+	
+    hdr.msg_iov = iov;
+    hdr.msg_iovlen = count;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
+    hdr.msg_accrights = NULL;
+    hdr.msg_accrightslen = 0;
+#else
+    hdr.msg_control = NULL;
+    hdr.msg_controllen = 0;
+    hdr.msg_flags = 0;
+#endif
+	
+	ws_sockaddr_free( hdr.msg_name, (struct WS_sockaddr *)0 );
+    n = sendmsg(fd, &hdr, dwFlags);
+
+    return n;
+}
+
+/* ************************************************************************************************ */
+/* ************************************************************************************************ */
+
+
 /***********************************************************************
  *		AcceptEx (MSWSOCK.@)
  *
@@ -90,8 +421,25 @@
     FIXME("not implemented\n");
 }
 
+
+/***********************************************************************
+ *		WSARecvEx (MSWSOCK.@)
+ */
+INT WINAPI WSARecvEx(
+	SOCKET s,   /* [in] Descriptor identifying a connected socket */
+	char *buf,  /* [out] Buffer for the incoming data */
+	INT len,    /* [in] Length of buf, in bytes */
+        INT *flags) /* [in/out] Indicator specifying whether the message is
+	               fully or partially received for datagram sockets */
+{
+    FIXME("not implemented\n");
+    
+    return SOCKET_ERROR;
+}
+
+
 /***********************************************************************
- *		TransmitFile (MSWSOCK.@)
+ *		TransmitFile(MSWSOCK.@)
  *
  * This function is used to transmit a file over socket.
  *
@@ -99,12 +447,17 @@
  *  This function is currently implemented as a stub.
  */
 
+static DWORD TransmitFileNormal(SOCKET s, int sd, int fd, struct iovec *iovec,
+								DWORD dwFlags, UINT dwJunkSize, size_t nFileLength);
+ 
+
 BOOL WINAPI TransmitFile(
         SOCKET hSocket, /* [in] Handle to a connected socket */
 	HANDLE hFile,   /* [in] Handle to the open file that should be
                            transmited */
 	DWORD nNumberOfBytesToWrite, /* [in] Number of file bytes to 
-                                        transmit */
+                                      transmit - starting offset can be set through OVERLAPPED
+							Offset and OffsetHigh fields */
 	DWORD nNumberOfBytesPerSend, /* [in] Size in bytes of each block of
                                          data sent in each send operation */
 	LPOVERLAPPED lpOverlapped, /* [in] Specify in order to achieve an 
@@ -113,24 +466,322 @@
 	LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, 
 		/* [in] Contains pointers to data to send before and after
                    the file data is sent */
-	DWORD dwFlags) /* [in] Flags */
+	DWORD dwFlags) /* [in] Flags */ 
 {
-    FIXME("not implemented\n");
+	unsigned int 	i			= 0;
+	long 		 	filelen		= 0;
+	DWORD 		 	filepos		= 0;
+	unsigned int 	nVectors 	= 0;
+	unsigned int	nFileJunks	= 0;
+	
+	int sd, fd , ret = 0;
+	struct iovec* iovec;
+
+	int FD_flags;
+	int SD_flags;
+
+	long flen;
+	
+	iovec = 0;
+	
+
+ TRACE("hSocket %04x, hFile %p, nbytes %ld, npsize %ld,  ovl %p, tfbuf %p, flags %ld\n",
+			hSocket, hFile, nNumberOfBytesToWrite, nNumberOfBytesPerSend, 
+			lpOverlapped, lpTransmitBuffers, dwFlags);	    
+	
+	if(nNumberOfBytesPerSend > FILE_DATA_BUFFER_LENGTH)
+		nNumberOfBytesPerSend = FILE_DATA_BUFFER_LENGTH; //we are using local var anyway ;-)
+	if(!nNumberOfBytesPerSend)
+		nNumberOfBytesPerSend = FILE_DATA_BUFFER_LENGTH; //we are using local var anyway ;-)		
+	
+	//check if the socket is usable
+	sd = get_sock_fd(hSocket, FILE_WRITE_DATA, &SD_flags);
+	TRACE( "sd=%d, flags=%x\n", sd, SD_flags);
+
+	if ( sd == -1 ) 
+	{
+		TRACE("Can't get sd!\n");
+		WSASetLastError(WSAEFAULT);
+		return SOCKET_ERROR;
+	}
+	
+ 	if(dwFlags & TF_REUSE_SOCKET)
+	{
+		 FIXME("TF_REUSE_SOCKET not yet implemented\n");
+		 WSASetLastError(WSAEINVAL);
+		 return FALSE;
+	}
+	
+	if(dwFlags & TF_DISCONNECT)
+	{
+		FIXME("TF_DISCONNECT not yet implemented\n");
+		WSASetLastError(WSAEINVAL);		
+		return FALSE;
+	} 
+	
+	if(lpOverlapped)
+	{
+		if(lpOverlapped->u.s.OffsetHigh)
+		{
+			FIXME("High order offset not currently supported\n");
+			WSASetLastError(WSAEINVAL);
+			return FALSE;
+		}
+	}
+	
+	//process file length
+	if(hFile)
+	{
+		TRACE("Processing file...\n");
+		
+		if(wine_server_handle_to_fd( hFile, FILE_READ_DATA, &fd, &FD_flags ))
+		{
+			TRACE("Get fd: ERROR!\n");
+			WSASetLastError(WSA_INVALID_PARAMETER);
+			return FALSE; 
+		}
+		
+		TRACE("Got fd: %d\n",fd);
+		
+		if(lpOverlapped)
+			filepos = lpOverlapped->u.s.Offset;
+		else
+			filepos = 0;
+			
+		lseek(fd, filepos, SEEK_SET);		/* back to offset */
+		flen=lseek(fd, 0,SEEK_END); 						/*get file length */
+		lseek(fd, filepos, SEEK_SET);		/* back to offset */
+	
+		
+		filelen = (flen < 0) ? 0 : flen;
+		
+		if(nNumberOfBytesToWrite)
+			filelen = (filelen < nNumberOfBytesToWrite) ? filelen : nNumberOfBytesToWrite;
+			
+		TRACE("TransmitFile: file length %ld\n",filelen);				
+		nFileJunks = filelen / nNumberOfBytesPerSend;
+		
+		if(filelen % nNumberOfBytesPerSend)
+			nFileJunks++;
+	}
+		
+
+	iovec = HeapAlloc(GetProcessHeap(), 0, 3 * sizeof(struct iovec));
+	memset(iovec, 0, 3 * sizeof(struct iovec));
+	nVectors = 3;
+	
+	TRACE("buffers created!\n");
+	
+	if(lpTransmitBuffers)
+	{
+		if(lpTransmitBuffers->Head && lpTransmitBuffers->HeadLength)
+		{
+			iovec[0].iov_base = lpTransmitBuffers->Head;
+			iovec[0].iov_len	= lpTransmitBuffers->HeadLength;
+			TRACE("Head mapped\n");
+		}
+		if(lpTransmitBuffers->Tail && lpTransmitBuffers->TailLength)
+		{
+			iovec[nVectors-1].iov_base = lpTransmitBuffers->Tail;
+			iovec[nVectors-1].iov_len	 = lpTransmitBuffers->TailLength;
+			TRACE("Tail mapped\n");
+		}
+	}
+	
+	if ( lpOverlapped && SD_flags & FD_FLAG_OVERLAPPED )
+	{
+		FIXME("Overlapped not functionable this time, sorry\n");
+		WSASetLastError(WSAENOBUFS);
+		goto e_exit;
+	}
+	
+	ret = TransmitFileNormal(hSocket,sd, fd, iovec, dwFlags, nNumberOfBytesPerSend, filelen);
+	
+	release_sock_fd( hSocket, sd );
+	if(iovec)
+	{
+		if(iovec[1].iov_base)
+			HeapFree(GetProcessHeap(), 0 , iovec[i].iov_base);
+		HeapFree( GetProcessHeap(), 0, iovec );
+	}
+	
+	return ret;
+	
+e_exit:
+
+	release_sock_fd( hSocket, sd );
+	if(iovec)
+	{
+		if(iovec[1].iov_base)
+			HeapFree(GetProcessHeap(), 0 , iovec[i].iov_base);
+		HeapFree( GetProcessHeap(), 0, iovec );
+	}
+	return FALSE;
+}
 
-    return FALSE;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+static DWORD TransmitFileNormal(SOCKET s, int sd, int fd, struct iovec *iovec, DWORD dwFlags, UINT dwJunkSize, size_t nFileLength)
+{
+	int err = WSAENOTSOCK;
+	size_t nBytesSent;
+	size_t nBytesRead;
+	size_t nBytesToSend;
+
+	TRACE("s: %d, sd: %d, fd: %d, iovec: %p, dwFlags: %ld, dwJunkSize: %u, nFileLength: %ld\n",
+			s, sd, fd, iovec, dwFlags, dwJunkSize, nFileLength);
+			
+	
+	if(iovec[0].iov_len)
+	{
+		nBytesToSend = iovec[0].iov_len;
+		while(nBytesToSend)
+		{
+			nBytesSent = send( s, &((char*)(iovec[0].iov_base))[nBytesSent], nBytesToSend, dwFlags );
+			if(nBytesSent == -1)
+				goto error;
+			nBytesToSend -= nBytesSent;
+		}
+	}
+	
+	iovec[1].iov_base = HeapAlloc(GetProcessHeap(), 0, dwJunkSize+1);
+	
+	nBytesSent = 0;
+	while(nFileLength)
+	{
+		int n; 
+		
+		nBytesRead = pread(fd, iovec[1].iov_base, dwJunkSize, nBytesSent);	
+		iovec[1].iov_len = nBytesRead;
+		
+		n = MWS2_send( sd, &iovec[1], 1, dwFlags );
+		/*n = send( s, iovec[1].iov_base, iovec[1].iov_len, dwFlags );*/
+		
+		if ( n == -1 )
+		{
+			err = wsaErrno();
+			if ( err == WSAEWOULDBLOCK )
+			{
+				_enable_event(SOCKET2HANDLE(s), FD_WRITE, 0, 0);
+				continue; /* We do not mind blocking, in fact this was expected */
+			}
+			goto error;
+		}
+		nFileLength -= n;
+		nBytesSent+=n;
+	}
+	
+	nBytesSent = 0;
+	if(iovec[2].iov_len)
+	{
+		nBytesToSend = iovec[2].iov_len;
+		while(nBytesToSend)
+		{
+			nBytesSent = send( s, &(iovec[2].iov_base[nBytesSent]), nBytesToSend, dwFlags );
+			if(nBytesSent == -1)
+				goto error;
+			nBytesToSend -= nBytesSent;
+		}
+	}
+	
+	return TRUE;
+	
+	error:
+	WSASetLastError( err); /*FIXME*/
+	return FALSE;
 }
 
-/***********************************************************************
- *		WSARecvEx (MSWSOCK.@)
- */
-INT WINAPI WSARecvEx(
-	SOCKET s,   /* [in] Descriptor identifying a connected socket */
-	char *buf,  /* [out] Buffer for the incoming data */
-	INT len,    /* [in] Length of buf, in bytes */
-        INT *flags) /* [in/out] Indicator specifying whether the message is
-	               fully or partially received for datagram sockets */
+
+/* *********************************************************************************** */
+/* ----------------------------------- error handling */
+
+UINT wsaErrno(void)
 {
-    FIXME("not implemented\n");
-    
-    return SOCKET_ERROR;
+    int	loc_errno = errno;
+    WARN("errno %d, (%s).\n", loc_errno, strerror(loc_errno));
+
+    switch(loc_errno)
+    {
+	case EINTR:		return WSAEINTR;
+	case EBADF:		return WSAEBADF;
+	case EPERM:
+	case EACCES:		return WSAEACCES;
+	case EFAULT:		return WSAEFAULT;
+	case EINVAL:		return WSAEINVAL;
+	case EMFILE:		return WSAEMFILE;
+	case EWOULDBLOCK:	return WSAEWOULDBLOCK;
+	case EINPROGRESS:	return WSAEINPROGRESS;
+	case EALREADY:		return WSAEALREADY;
+	case ENOTSOCK:		return WSAENOTSOCK;
+	case EDESTADDRREQ:	return WSAEDESTADDRREQ;
+	case EMSGSIZE:		return WSAEMSGSIZE;
+	case EPROTOTYPE:	return WSAEPROTOTYPE;
+	case ENOPROTOOPT:	return WSAENOPROTOOPT;
+	case EPROTONOSUPPORT:	return WSAEPROTONOSUPPORT;
+	case ESOCKTNOSUPPORT:	return WSAESOCKTNOSUPPORT;
+	case EOPNOTSUPP:	return WSAEOPNOTSUPP;
+	case EPFNOSUPPORT:	return WSAEPFNOSUPPORT;
+	case EAFNOSUPPORT:	return WSAEAFNOSUPPORT;
+	case EADDRINUSE:	return WSAEADDRINUSE;
+	case EADDRNOTAVAIL:	return WSAEADDRNOTAVAIL;
+	case ENETDOWN:		return WSAENETDOWN;
+	case ENETUNREACH:	return WSAENETUNREACH;
+	case ENETRESET:		return WSAENETRESET;
+	case ECONNABORTED:	return WSAECONNABORTED;
+	case EPIPE:
+	case ECONNRESET:	return WSAECONNRESET;
+	case ENOBUFS:		return WSAENOBUFS;
+	case EISCONN:		return WSAEISCONN;
+	case ENOTCONN:		return WSAENOTCONN;
+	case ESHUTDOWN:		return WSAESHUTDOWN;
+	case ETOOMANYREFS:	return WSAETOOMANYREFS;
+	case ETIMEDOUT:		return WSAETIMEDOUT;
+	case ECONNREFUSED:	return WSAECONNREFUSED;
+	case ELOOP:		return WSAELOOP;
+	case ENAMETOOLONG:	return WSAENAMETOOLONG;
+	case EHOSTDOWN:		return WSAEHOSTDOWN;
+	case EHOSTUNREACH:	return WSAEHOSTUNREACH;
+	case ENOTEMPTY:		return WSAENOTEMPTY;
+#ifdef EPROCLIM
+	case EPROCLIM:		return WSAEPROCLIM;
+#endif
+#ifdef EUSERS
+	case EUSERS:		return WSAEUSERS;
+#endif
+#ifdef EDQUOT
+	case EDQUOT:		return WSAEDQUOT;
+#endif
+#ifdef ESTALE
+	case ESTALE:		return WSAESTALE;
+#endif
+#ifdef EREMOTE
+	case EREMOTE:		return WSAEREMOTE;
+#endif
+
+       /* just in case we ever get here and there are no problems */
+	case 0:			return 0;
+        default:
+		WARN("Unknown errno %d!\n", loc_errno);
+		return WSAEOPNOTSUPP;
+    }
+}
+
+UINT wsaHerrno(int loc_errno)
+{
+
+    WARN("h_errno %d.\n", loc_errno);
+
+    switch(loc_errno)
+    {
+	case HOST_NOT_FOUND:	return WSAHOST_NOT_FOUND;
+	case TRY_AGAIN:		return WSATRY_AGAIN;
+	case NO_RECOVERY:	return WSANO_RECOVERY;
+	case NO_DATA:		return WSANO_DATA;
+	case ENOBUFS:		return WSAENOBUFS;
+
+	case 0:			return 0;
+        default:
+		WARN("Unknown h_errno %d!\n", loc_errno);
+		return WSAEOPNOTSUPP;
+    }
 }
Index: dlls/mswsock/mswsock.spec
===================================================================
RCS file: /home/wine/wine/dlls/mswsock/mswsock.spec,v
retrieving revision 1.4
diff -u -r1.4 mswsock.spec
--- dlls/mswsock/mswsock.spec	21 Nov 2005 11:58:49 -0000	1.4
+++ dlls/mswsock/mswsock.spec	25 Jun 2006 22:56:26 -0000
@@ -19,7 +19,8 @@
 @ stub StartWsdpService
 @ stub StopWsdpService
 @ stub SvchostPushServiceGlobals
-@ stdcall TransmitFile(long long long long ptr ptr long)
+@ stdcall TransmitFile(long long long long ptr ptr long) TransmitFile
+@ stub TransmitPackets
 @ stub WSARecvEx
 @ stub WSPStartup
 @ stub dn_expand


More information about the wine-patches mailing list