[3/4] ws2_32: Add extended IPX protocol support (try 2)
Bruno Jesus
00cpxxx at gmail.com
Fri Dec 27 10:56:18 CST 2013
try 2:
Fix the error check when no ipx is available.
original:
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>
-------------- next part --------------
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 6b06ee5..8911048 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 {
@@ -1110,6 +1112,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;
}
@@ -1121,6 +1128,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;
}
@@ -5953,7 +5966,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,
@@ -5988,13 +6001,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;
@@ -6005,6 +6021,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);
@@ -6059,7 +6083,10 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
SERVER_END_REQ;
if (ret)
{
- TRACE("\tcreated %04lx\n", ret );
+ if (ipxptype >= 0)
+ set_ipx_ptype(ret, ipxptype);
+
+ TRACE("\tcreated %04lx\n", ret );
return ret;
}
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 341b7e7..815cbbb 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)
More information about the wine-patches
mailing list