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