ws2_32: Implement get socket option SO_PROTOCOL_INFO.
This commit is contained in:
parent
f031c676c1
commit
dea4f7bc02
|
@ -1747,6 +1747,40 @@ static INT WS_EnumProtocols( BOOL unicode, const INT *protocols, LPWSAPROTOCOL_I
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
*size = unicode ? sizeof(WSAPROTOCOL_INFOW) : sizeof(WSAPROTOCOL_INFOA);
|
||||||
|
memset(buffer, 0, *size);
|
||||||
|
|
||||||
|
SERVER_START_REQ( get_socket_info )
|
||||||
|
{
|
||||||
|
req->handle = wine_server_obj_handle( SOCKET2HANDLE(s) );
|
||||||
|
status = wine_server_call( req );
|
||||||
|
if (!status)
|
||||||
|
{
|
||||||
|
buffer->iAddressFamily = convert_af_u2w(reply->family);
|
||||||
|
buffer->iSocketType = convert_socktype_u2w(reply->type);
|
||||||
|
buffer->iProtocol = convert_proto_u2w(reply->protocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
set_error(status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unicode)
|
||||||
|
WS_EnterSingleProtocolW( buffer->iProtocol, buffer);
|
||||||
|
else
|
||||||
|
WS_EnterSingleProtocolA( buffer->iProtocol, (WSAPROTOCOL_INFOA *)buffer);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Functions for handling overlapped I/O
|
* Functions for handling overlapped I/O
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -3024,7 +3058,26 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
|
||||||
*optlen = sizeof(int);
|
*optlen = sizeof(int);
|
||||||
TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
|
TRACE("getting global SO_OPENTYPE = 0x%x\n", *((int*)optval) );
|
||||||
return 0;
|
return 0;
|
||||||
|
case WS_SO_PROTOCOL_INFOA:
|
||||||
|
case WS_SO_PROTOCOL_INFOW:
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
WSAPROTOCOL_INFOW infow;
|
||||||
|
|
||||||
|
ret = ws_protocol_info(s, optname == WS_SO_PROTOCOL_INFOW, &infow, &size);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
if (!optlen || !optval || *optlen < size)
|
||||||
|
{
|
||||||
|
if(optlen) *optlen = size;
|
||||||
|
ret = 0;
|
||||||
|
SetLastError(WSAEFAULT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy(optval, &infow, size);
|
||||||
|
}
|
||||||
|
return ret ? 0 : SOCKET_ERROR;
|
||||||
|
}
|
||||||
#ifdef SO_RCVTIMEO
|
#ifdef SO_RCVTIMEO
|
||||||
case WS_SO_RCVTIMEO:
|
case WS_SO_RCVTIMEO:
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1235,29 +1235,40 @@ todo_wine
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
|
|
||||||
/* test SO_PROTOCOL_INFOA invalid parameters */
|
/* test SO_PROTOCOL_INFOA invalid parameters */
|
||||||
|
ok(getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
|
||||||
|
"getsockopt should have failed\n");
|
||||||
|
err = WSAGetLastError();
|
||||||
|
ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
|
||||||
|
size = sizeof(WSAPROTOCOL_INFOA);
|
||||||
|
ok(getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
|
||||||
|
"getsockopt should have failed\n");
|
||||||
|
ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
|
||||||
|
err = WSAGetLastError();
|
||||||
|
ok(err == WSAENOTSOCK, "expected 10038, got %d instead\n", err);
|
||||||
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
|
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, NULL),
|
||||||
"getsockopt should have failed\n");
|
"getsockopt should have failed\n");
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
todo_wine
|
|
||||||
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
||||||
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, NULL),
|
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, NULL),
|
||||||
"getsockopt should have failed\n");
|
"getsockopt should have failed\n");
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
todo_wine
|
|
||||||
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
||||||
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, &size),
|
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, NULL, &size),
|
||||||
"getsockopt should have failed\n");
|
"getsockopt should have failed\n");
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
todo_wine
|
|
||||||
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
||||||
|
|
||||||
size = sizeof(WSAPROTOCOL_INFOA) / 2;
|
size = sizeof(WSAPROTOCOL_INFOA) / 2;
|
||||||
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
|
ok(getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size),
|
||||||
"getsockopt should have failed\n");
|
"getsockopt should have failed\n");
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
todo_wine
|
|
||||||
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
ok(err == WSAEFAULT, "expected 10014, got %d instead\n", err);
|
||||||
|
ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
|
||||||
|
size = sizeof(WSAPROTOCOL_INFOA) * 2;
|
||||||
|
err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
|
||||||
|
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
ok(size == sizeof(WSAPROTOCOL_INFOA) * 2, "got size %d\n", size);
|
||||||
|
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
|
|
||||||
/* test SO_PROTOCOL_INFO structure returned for different protocols */
|
/* test SO_PROTOCOL_INFO structure returned for different protocols */
|
||||||
|
@ -1273,40 +1284,46 @@ todo_wine
|
||||||
infoA.szProtocol[0] = 0;
|
infoA.szProtocol[0] = 0;
|
||||||
size = sizeof(WSAPROTOCOL_INFOA);
|
size = sizeof(WSAPROTOCOL_INFOA);
|
||||||
err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
|
err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &infoA, &size);
|
||||||
todo_wine
|
|
||||||
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
ok(size == sizeof(WSAPROTOCOL_INFOA), "got size %d\n", size);
|
||||||
|
|
||||||
infoW.szProtocol[0] = 0;
|
infoW.szProtocol[0] = 0;
|
||||||
size = sizeof(WSAPROTOCOL_INFOW);
|
size = sizeof(WSAPROTOCOL_INFOW);
|
||||||
err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOW, (char *) &infoW, &size);
|
err = getsockopt(s, SOL_SOCKET, SO_PROTOCOL_INFOW, (char *) &infoW, &size);
|
||||||
todo_wine
|
|
||||||
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
ok(size == sizeof(WSAPROTOCOL_INFOW), "got size %d\n", size);
|
||||||
|
|
||||||
trace("provider name '%s', family %d, type %d, proto %d\n",
|
trace("provider name '%s', family %d, type %d, proto %d\n",
|
||||||
infoA.szProtocol, prottest[i].family, prottest[i].type, prottest[i].proto);
|
infoA.szProtocol, prottest[i].family, prottest[i].type, prottest[i].proto);
|
||||||
|
|
||||||
todo_wine {
|
|
||||||
ok(infoA.szProtocol[0] || broken(!infoA.szProtocol[0]) /* NT4 */,
|
ok(infoA.szProtocol[0] || broken(!infoA.szProtocol[0]) /* NT4 */,
|
||||||
"WSAPROTOCOL_INFOA was not filled\n");
|
"WSAPROTOCOL_INFOA was not filled\n");
|
||||||
ok(infoW.szProtocol[0] || broken(!infoA.szProtocol[0]) /* NT4 */,
|
ok(infoW.szProtocol[0] || broken(!infoA.szProtocol[0]) /* NT4 */,
|
||||||
"WSAPROTOCOL_INFOW was not filled\n");
|
"WSAPROTOCOL_INFOW was not filled\n");
|
||||||
}
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, infoW.szProtocol, -1,
|
WideCharToMultiByte(CP_ACP, 0, infoW.szProtocol, -1,
|
||||||
providername, sizeof(providername), NULL, NULL);
|
providername, sizeof(providername), NULL, NULL);
|
||||||
ok(!strcmp(infoA.szProtocol,providername),
|
ok(!strcmp(infoA.szProtocol,providername),
|
||||||
"different provider names '%s' != '%s'\n", infoA.szProtocol, providername);
|
"different provider names '%s' != '%s'\n", infoA.szProtocol, providername);
|
||||||
|
|
||||||
todo_wine {
|
|
||||||
ok(!memcmp(&infoA, &infoW, FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol)),
|
ok(!memcmp(&infoA, &infoW, FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol)),
|
||||||
"SO_PROTOCOL_INFO[A/W] comparison failed\n");
|
"SO_PROTOCOL_INFO[A/W] comparison failed\n");
|
||||||
ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n",
|
|
||||||
prottest[i].family, infoA.iAddressFamily);
|
/* Remove IF when WSAEnumProtocols support IPV6 data */
|
||||||
ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n",
|
if (prottest[i].family == AF_INET6)
|
||||||
|
{
|
||||||
|
todo_wine
|
||||||
|
ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n",
|
||||||
|
prottest[i].family, infoA.iAddressFamily);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(infoA.iAddressFamily == prottest[i].family, "socket family invalid, expected %d received %d\n",
|
||||||
|
prottest[i].family, infoA.iAddressFamily);
|
||||||
|
} ok(infoA.iSocketType == prottest[i].type, "socket type invalid, expected %d received %d\n",
|
||||||
prottest[i].type, infoA.iSocketType);
|
prottest[i].type, infoA.iSocketType);
|
||||||
ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n",
|
ok(infoA.iProtocol == prottest[i].proto, "socket protocol invalid, expected %d received %d\n",
|
||||||
prottest[i].proto, infoA.iProtocol);
|
prottest[i].proto, infoA.iProtocol);
|
||||||
}
|
|
||||||
|
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue