#4 in series (incremental) Patch file: 004-socket.diff Purpose: Move socket() functionality to WS2_32 code Created: 2002-01-07 Applies: CVS 2002-01-07 (with 003-sock_basic.diff applied) This patch moves the functionality of WS_socket() to WSASocketA(). WSASocketA() accounts for WSA_FLAG_OVERLAPPED. dlls/winsock/socket.c: WS_socket(): Is now a wrapper around WSASocketA(). WSA_FLAG_OVERLAPPED is set according to the SO_OPENTYPE value. WSASocketA(): Has the functionality formerly in WS_socket(). Honours WSA_FLAG_OVERLAPPED. Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com> diff -ru -X diffignore CVS/wine/dlls/winsock/socket.c MW/wine/dlls/winsock/socket.c --- CVS/wine/dlls/winsock/socket.c Mon Jan 7 12:45:56 2002 +++ MW/wine/dlls/winsock/socket.c Mon Jan 7 12:51:27 2002 @@ -2329,81 +2329,14 @@ */ SOCKET WINAPI WS_socket(int af, int type, int protocol) { - SOCKET ret; - TRACE("af=%d type=%d protocol=%d\n", af, type, protocol); - /* check the socket family */ - switch(af) - { -#ifdef HAVE_IPX - case WS_AF_IPX: af = AF_IPX; -#endif - case AF_INET: - case AF_UNSPEC: break; - default: SetLastError(WSAEAFNOSUPPORT); - return INVALID_SOCKET; - } - - /* check the socket type */ - switch(type) - { - case WS_SOCK_STREAM: - type=SOCK_STREAM; - break; - case WS_SOCK_DGRAM: - type=SOCK_DGRAM; - break; - case WS_SOCK_RAW: - type=SOCK_RAW; - break; - default: SetLastError(WSAESOCKTNOSUPPORT); - return INVALID_SOCKET; - } - - /* check the protocol type */ - if ( protocol < 0 ) /* don't support negative values */ - { SetLastError(WSAEPROTONOSUPPORT); return INVALID_SOCKET; } - - if ( af == AF_UNSPEC) /* did they not specify the address family? */ - switch(protocol) - { - case IPPROTO_TCP: - if (type == SOCK_STREAM) { af = AF_INET; break; } - case IPPROTO_UDP: - if (type == SOCK_DGRAM) { af = AF_INET; break; } - default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET; - } - - SERVER_START_REQ( create_socket ) - { - req->family = af; - req->type = type; - req->protocol = protocol; - req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; - req->flags = 0U; - req->inherit = TRUE; - set_error( wine_server_call( req ) ); - ret = (SOCKET)reply->handle; - } - SERVER_END_REQ; - if (ret) - { - TRACE("\tcreated %04x\n", ret ); - return ret; - } - - if (GetLastError() == WSAEACCES) /* raw socket denied */ - { - if (type == SOCK_RAW) - MESSAGE("WARNING: Trying to create a socket of type SOCK_RAW, will fail unless running as root\n"); - else - MESSAGE("WS_SOCKET: not enough privileges to create socket, try running as root\n"); - SetLastError(WSAESOCKTNOSUPPORT); - } + /* The Winsock2 specification states that socket() always opens sockets + in overlapped mode. + FIXME: is the SO_OPENTYPE behaviour correct? */ - WARN("\t\tfailed!\n"); - return INVALID_SOCKET; + return WSASocketA ( af, type, protocol, NULL, 0, + (opentype ? 0 : WSA_FLAG_OVERLAPPED) ); } /*********************************************************************** @@ -2974,17 +2907,88 @@ LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags) { + SOCKET ret; + /* FIXME: The "advanced" parameters of WSASocketA (lpProtocolInfo, - g, dwFlags) are ignored. + g, dwFlags except WSA_FLAG_OVERLAPPED) are ignored. */ TRACE("af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%lx\n", af, type, protocol, lpProtocolInfo, g, dwFlags ); - return ( WS_socket (af, type, protocol) ); -} + /* check the socket family */ + switch(af) + { +#ifdef HAVE_IPX + case WS_AF_IPX: af = AF_IPX; +#endif + case AF_INET: + case AF_UNSPEC: break; + default: SetLastError(WSAEAFNOSUPPORT); + return INVALID_SOCKET; + } + + /* check the socket type */ + switch(type) + { + case WS_SOCK_STREAM: + type=SOCK_STREAM; + break; + case WS_SOCK_DGRAM: + type=SOCK_DGRAM; + break; + case WS_SOCK_RAW: + type=SOCK_RAW; + break; + default: SetLastError(WSAESOCKTNOSUPPORT); + return INVALID_SOCKET; + } + + /* check the protocol type */ + if ( protocol < 0 ) /* don't support negative values */ + { SetLastError(WSAEPROTONOSUPPORT); return INVALID_SOCKET; } + + if ( af == AF_UNSPEC) /* did they not specify the address family? */ + switch(protocol) + { + case IPPROTO_TCP: + if (type == SOCK_STREAM) { af = AF_INET; break; } + case IPPROTO_UDP: + if (type == SOCK_DGRAM) { af = AF_INET; break; } + default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET; + } + + SERVER_START_REQ( create_socket ) + { + req->family = af; + req->type = type; + req->protocol = protocol; + req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; + req->flags = dwFlags; + req->inherit = TRUE; + set_error( wine_server_call( req ) ); + ret = (SOCKET)reply->handle; + } + SERVER_END_REQ; + if (ret) + { + TRACE("\tcreated %04x\n", ret ); + return ret; + } + + if (GetLastError() == WSAEACCES) /* raw socket denied */ + { + if (type == SOCK_RAW) + MESSAGE("WARNING: Trying to create a socket of type SOCK_RAW, will fail unless running as root\n"); + else + MESSAGE("WS_SOCKET: not enough privileges to create socket, try running as root\n"); + SetLastError(WSAESOCKTNOSUPPORT); + } + WARN("\t\tfailed!\n"); + return INVALID_SOCKET; +} /*********************************************************************** * __WSAFDIsSet (WINSOCK.151)