Module: wine Branch: master Commit: 3eb39dc08e67cb33bd6dadbbe14af46dd8673ead URL: http://source.winehq.org/git/wine.git/?a=commit;h=3eb39dc08e67cb33bd6dadbbe1...
Author: Bruno Jesus 00cpxxx@gmail.com Date: Mon Dec 30 22:25:09 2013 -0200
ws2_32: Add extended IPX protocol support.
---
dlls/ws2_32/socket.c | 36 ++++++++++++++++++++--- dlls/ws2_32/tests/sock.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 732bbad..462ff86 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -201,6 +201,8 @@ static const INT valid_protocols[] = 0 };
+#define IS_IPX_PROTO(X) ((X) >= WS_NSPROTO_IPX && (X) <= WS_NSPROTO_IPX + 255) + #if defined(IP_UNICAST_IF) && defined(SO_ATTACH_FILTER) # define LINUX_BOUND_IF struct interface_filter { @@ -1122,6 +1124,11 @@ convert_proto_w2u(int windowsproto) { for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++) if (ws_proto_map[i][0] == windowsproto) return ws_proto_map[i][1]; + + /* check for extended IPX */ + if (IS_IPX_PROTO(windowsproto)) + return windowsproto; + FIXME("unhandled Windows socket protocol %d\n", windowsproto); return -1; } @@ -1133,6 +1140,12 @@ convert_proto_u2w(int unixproto) { for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++) if (ws_proto_map[i][1] == unixproto) return ws_proto_map[i][0]; + + /* if value is inside IPX range just return it - the kernel simply + * echoes the value used in the socket() function */ + if (IS_IPX_PROTO(unixproto)) + return unixproto; + FIXME("unhandled UNIX socket protocol %d\n", unixproto); return -1; } @@ -5976,7 +5989,7 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, { SOCKET ret; DWORD err; - int unixaf, unixtype; + int unixaf, unixtype, ipxptype = -1;
/* FIXME: The "advanced" parameters of WSASocketW (lpProtocolInfo, @@ -6011,13 +6024,16 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
if (!type && (af || protocol)) { + int autoproto = protocol; WSAPROTOCOL_INFOW infow;
/* default to the first valid protocol */ - if (!protocol) - protocol = valid_protocols[0]; + if (!autoproto) + autoproto = valid_protocols[0]; + else if(IS_IPX_PROTO(autoproto)) + autoproto = WS_NSPROTO_IPX;
- if (WS_EnterSingleProtocolW(protocol, &infow)) + if (WS_EnterSingleProtocolW(autoproto, &infow)) { type = infow.iSocketType;
@@ -6028,6 +6044,14 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, } }
+ /* + Windows has an extension to the IPX protocol that allows to create sockets + and set the IPX packet type at the same time, to do that a caller will use + a protocol like NSPROTO_IPX + <PACKET TYPE> + */ + if (IS_IPX_PROTO(protocol)) + ipxptype = protocol - WS_NSPROTO_IPX; + /* convert the socket family, type and protocol */ unixaf = convert_af_w2u(af); unixtype = convert_socktype_w2u(type); @@ -6083,7 +6107,9 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, if (ret) { TRACE("\tcreated %04lx\n", ret ); - return ret; + if (ipxptype > 0) + set_ipx_packettype(ret, ipxptype); + return ret; }
err = GetLastError(); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 7bb39f7..59c356c 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -26,6 +26,8 @@ #include <windows.h> #include <winternl.h> #include <ws2tcpip.h> +#include <wsipx.h> +#include <wsnwlink.h> #include <mswsock.h> #include <mstcpip.h> #include <stdio.h> @@ -2088,6 +2090,73 @@ static void test_WSASocket(void) SOCK_RAW, socktype); closesocket(sock); } + + /* IPX socket tests */ + + SetLastError(0xdeadbeef); + sock = WSASocketA(AF_IPX, SOCK_DGRAM, NSPROTO_IPX, NULL, 0, 0); + if (sock == INVALID_SOCKET) + { + err = WSAGetLastError(); + ok(err == WSAEAFNOSUPPORT || broken(err == WSAEPROTONOSUPPORT), "Expected 10047, received %d\n", err); + skip("IPX is not supported\n"); + } + else + { + WSAPROTOCOL_INFOA info; + closesocket(sock); + + trace("IPX is supported\n"); + + sock = WSASocketA(0, 0, NSPROTO_IPX, NULL, 0, 0); + ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n", + WSAGetLastError()); + + size = sizeof(socktype); + socktype = 0xdead; + err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size); + ok(!err,"getsockopt failed with %d\n", WSAGetLastError()); + ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n", + SOCK_DGRAM, socktype); + + /* check socket family, type and protocol */ + size = sizeof(WSAPROTOCOL_INFOA); + err = getsockopt(sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &info, &size); + ok(!err,"getsockopt failed with %d\n", WSAGetLastError()); + ok(info.iProtocol == NSPROTO_IPX, "expected protocol %d, received %d\n", + NSPROTO_IPX, info.iProtocol); + ok(info.iAddressFamily == AF_IPX, "expected family %d, received %d\n", + AF_IPX, info.iProtocol); + ok(info.iSocketType == SOCK_DGRAM, "expected type %d, received %d\n", + SOCK_DGRAM, info.iSocketType); + closesocket(sock); + + /* SOCK_STREAM does not support NSPROTO_IPX */ + SetLastError(0xdeadbeef); + ok(WSASocketA(AF_IPX, SOCK_STREAM, NSPROTO_IPX, NULL, 0, 0) == INVALID_SOCKET, + "WSASocketA should have failed\n"); + err = WSAGetLastError(); + ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err); + + /* test extended IPX support - that is adding any number between 0 and 255 + * to the IPX protocol value will make it be used as IPX packet type */ + for(i = 0;i <= 255;i += 17) + { + SetLastError(0xdeadbeef); + sock = WSASocketA(0, 0, NSPROTO_IPX + i, NULL, 0, 0); + ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n", + WSAGetLastError()); + + size = sizeof(int); + socktype = -1; + err = getsockopt(sock, NSPROTO_IPX, IPX_PTYPE, (char *) &socktype, &size); + ok(!err, "getsockopt failed with %d\n", WSAGetLastError()); + ok(socktype == i, "Wrong IPX packet type, expected %d received %d\n", + i, socktype); + + closesocket(sock); + } + } }
static void test_WSADuplicateSocket(void)