ws2_32: Implement getsockopt(SO_BSP_STATE).
This commit is contained in:
parent
550f556dca
commit
1c4cb63036
|
@ -3095,6 +3095,79 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
|
||||||
}
|
}
|
||||||
release_sock_fd( s, fd );
|
release_sock_fd( s, fd );
|
||||||
return ret;
|
return ret;
|
||||||
|
case WS_SO_BSP_STATE:
|
||||||
|
{
|
||||||
|
int req_size, addr_size;
|
||||||
|
WSAPROTOCOL_INFOW infow;
|
||||||
|
CSADDR_INFO *csinfo;
|
||||||
|
|
||||||
|
ret = ws_protocol_info(s, TRUE, &infow, &addr_size);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (infow.iAddressFamily == WS_AF_INET)
|
||||||
|
addr_size = sizeof(struct sockaddr_in);
|
||||||
|
else if (infow.iAddressFamily == WS_AF_INET6)
|
||||||
|
addr_size = sizeof(struct sockaddr_in6);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FIXME("Family %d is unsupported for SO_BSP_STATE", infow.iAddressFamily);
|
||||||
|
SetLastError(WSAEAFNOSUPPORT);
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_size = sizeof(CSADDR_INFO) + addr_size * 2;
|
||||||
|
if (*optlen < req_size)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
SetLastError(WSAEFAULT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
union generic_unix_sockaddr uaddr;
|
||||||
|
socklen_t uaddrlen = sizeof(uaddr);
|
||||||
|
|
||||||
|
if ( (fd = get_sock_fd( s, 0, NULL )) == -1)
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
|
csinfo = (CSADDR_INFO*) optval;
|
||||||
|
|
||||||
|
/* Check if the sock is bound */
|
||||||
|
if (!getsockname(fd, &uaddr.addr, &uaddrlen) &&
|
||||||
|
is_sockaddr_bound(&uaddr.addr, uaddrlen))
|
||||||
|
{
|
||||||
|
csinfo->LocalAddr.lpSockaddr =
|
||||||
|
(LPSOCKADDR) (optval + sizeof(CSADDR_INFO));
|
||||||
|
ws_sockaddr_u2ws(&uaddr.addr, csinfo->LocalAddr.lpSockaddr, &addr_size);
|
||||||
|
csinfo->LocalAddr.iSockaddrLength = addr_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
csinfo->LocalAddr.lpSockaddr = NULL;
|
||||||
|
csinfo->LocalAddr.iSockaddrLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the sock is connected */
|
||||||
|
if (!getpeername(fd, &uaddr.addr, &uaddrlen) &&
|
||||||
|
is_sockaddr_bound(&uaddr.addr, uaddrlen))
|
||||||
|
{
|
||||||
|
csinfo->RemoteAddr.lpSockaddr =
|
||||||
|
(LPSOCKADDR) (optval + sizeof(CSADDR_INFO) + addr_size);
|
||||||
|
ws_sockaddr_u2ws(&uaddr.addr, csinfo->RemoteAddr.lpSockaddr, &addr_size);
|
||||||
|
csinfo->RemoteAddr.iSockaddrLength = addr_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
csinfo->RemoteAddr.lpSockaddr = NULL;
|
||||||
|
csinfo->RemoteAddr.iSockaddrLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
csinfo->iSocketType = infow.iSocketType;
|
||||||
|
csinfo->iProtocol = infow.iProtocol;
|
||||||
|
release_sock_fd( s, fd );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret ? 0 : SOCKET_ERROR;
|
||||||
|
}
|
||||||
case WS_SO_DONTLINGER:
|
case WS_SO_DONTLINGER:
|
||||||
{
|
{
|
||||||
struct linger lingval;
|
struct linger lingval;
|
||||||
|
|
|
@ -1486,9 +1486,9 @@ todo_wine
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test SO_BSP_STATE - Present only in >= Win 2008 */
|
/* Test SO_BSP_STATE - Present only in >= Win 2008 */
|
||||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
ok(s != INVALID_SOCKET, "Failed to create socket\n");
|
ok(s != INVALID_SOCKET, "Failed to create socket\n");
|
||||||
s2 = socket(AF_INET, SOCK_STREAM, 0);
|
s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
ok(s2 != INVALID_SOCKET, "Failed to create socket\n");
|
ok(s2 != INVALID_SOCKET, "Failed to create socket\n");
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
|
@ -1571,6 +1571,23 @@ todo_wine
|
||||||
ok(!err, "Expected 0, got %d\n", err);
|
ok(!err, "Expected 0, got %d\n", err);
|
||||||
ok(!memcmp(&saddr, csinfoB.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
|
ok(!memcmp(&saddr, csinfoB.cs.LocalAddr.lpSockaddr, size), "Expected matching addresses\n");
|
||||||
ok(!memcmp(&saddr, csinfoA.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
|
ok(!memcmp(&saddr, csinfoA.cs.RemoteAddr.lpSockaddr, size), "Expected matching addresses\n");
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
size = sizeof(CSADDR_INFO);
|
||||||
|
err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
|
||||||
|
ok(err, "Expected non-zero\n");
|
||||||
|
ok(size == sizeof(CSADDR_INFO), "Got %d\n", size);
|
||||||
|
ok(GetLastError() == WSAEFAULT, "Expected 10014, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
/* At least for IPv4 the size is exactly 56 bytes */
|
||||||
|
size = sizeof(*csinfoA.cs.LocalAddr.lpSockaddr) * 2 + sizeof(csinfoA.cs);
|
||||||
|
err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
|
||||||
|
ok(!err, "Expected 0, got %d\n", err);
|
||||||
|
size--;
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
err = getsockopt(s, SOL_SOCKET, SO_BSP_STATE, (char *) &csinfoA, &size);
|
||||||
|
ok(err, "Expected non-zero\n");
|
||||||
|
ok(GetLastError() == WSAEFAULT, "Expected 10014, got %d\n", GetLastError());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %d\n", GetLastError());
|
ok(GetLastError() == WSAENOPROTOOPT, "Expected 10042, got %d\n", GetLastError());
|
||||||
|
|
|
@ -697,6 +697,7 @@ typedef struct WS(WSAData)
|
||||||
#define WS_SO_RCVTIMEO 0x1006
|
#define WS_SO_RCVTIMEO 0x1006
|
||||||
#define WS_SO_ERROR 0x1007
|
#define WS_SO_ERROR 0x1007
|
||||||
#define WS_SO_TYPE 0x1008
|
#define WS_SO_TYPE 0x1008
|
||||||
|
#define WS_SO_BSP_STATE 0x1009
|
||||||
|
|
||||||
#define WS_IOCPARM_MASK 0x7f
|
#define WS_IOCPARM_MASK 0x7f
|
||||||
#define WS_IOC_VOID 0x20000000
|
#define WS_IOC_VOID 0x20000000
|
||||||
|
|
Loading…
Reference in New Issue