ws2_32: Add extended IPX protocol support.

oldstable
Bruno Jesus 2013-12-30 22:25:09 -02:00 committed by Alexandre Julliard
parent 2d4adfc49e
commit 3eb39dc08e
2 changed files with 100 additions and 5 deletions

View File

@ -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();

View File

@ -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)