Skip to content

Commit 0c8e44e

Browse files
[MSAFD][AFD] Implement AcceptEx
1 parent ab2393c commit 0c8e44e

9 files changed

Lines changed: 410 additions & 63 deletions

File tree

dll/win32/msafd/misc/dllmain.c

Lines changed: 123 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,123 @@ WSPAccept(
18421842
return AcceptSocket;
18431843
}
18441844

1845+
BOOL
1846+
WSPAPI
1847+
WSPAcceptEx(
1848+
IN SOCKET sListenSocket,
1849+
IN SOCKET sAcceptSocket,
1850+
OUT PVOID lpOutputBuffer,
1851+
IN DWORD dwReceiveDataLength,
1852+
IN DWORD dwLocalAddressLength,
1853+
IN DWORD dwRemoteAddressLength,
1854+
OUT LPDWORD lpdwBytesReceived,
1855+
IN OUT LPOVERLAPPED lpOverlapped)
1856+
{
1857+
PSOCKET_INFORMATION ListenSocket = NULL;
1858+
PSOCKET_INFORMATION AcceptSocket = NULL;
1859+
AFD_SUPER_ACCEPT_INFO AcceptInfo;
1860+
NTSTATUS Status;
1861+
PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
1862+
1863+
/* Validate sockets */
1864+
ListenSocket = GetSocketStructure(sListenSocket);
1865+
AcceptSocket = GetSocketStructure(sAcceptSocket);
1866+
if (!ListenSocket || !AcceptSocket)
1867+
{
1868+
SetLastError(WSAENOTSOCK);
1869+
return FALSE;
1870+
}
1871+
1872+
if (!lpOverlapped)
1873+
{
1874+
SetLastError(ERROR_INVALID_PARAMETER);
1875+
return FALSE;
1876+
}
1877+
1878+
/* Check if this socket is listening and that AcceptEx hasn't already been invoked */
1879+
if (!ListenSocket->SharedData->Listening)
1880+
{
1881+
SetLastError(WSAEINVAL);
1882+
return FALSE;
1883+
}
1884+
1885+
/* Make sure that the accept socket is not already opened or connected */
1886+
if (AcceptSocket->SharedData->State != SocketOpen)
1887+
{
1888+
SetLastError(WSAEINVAL);
1889+
return FALSE;
1890+
}
1891+
1892+
if (!lpOutputBuffer || !dwRemoteAddressLength)
1893+
{
1894+
SetLastError(WSAEFAULT);
1895+
return FALSE;
1896+
}
1897+
1898+
/* Populate IOCTL super accept structure */
1899+
AcceptInfo.SanActive = FALSE;
1900+
AcceptInfo.FixAddressAlignment = TRUE;
1901+
AcceptInfo.AcceptHandle = (HANDLE)AcceptSocket->Handle;
1902+
AcceptInfo.ReceiveDataLength = dwReceiveDataLength;
1903+
AcceptInfo.LocalAddressLength = dwLocalAddressLength;
1904+
AcceptInfo.RemoteAddressLength = dwRemoteAddressLength;
1905+
1906+
IoStatusBlock->Information = 0;
1907+
IoStatusBlock->Status = STATUS_PENDING;
1908+
1909+
Status = NtDeviceIoControlFile((HANDLE)ListenSocket->Handle,
1910+
lpOverlapped->hEvent,
1911+
NULL,
1912+
lpOverlapped->hEvent ? NULL : lpOverlapped,
1913+
IoStatusBlock,
1914+
IOCTL_AFD_SUPER_ACCEPT,
1915+
&AcceptInfo,
1916+
sizeof(AcceptInfo),
1917+
lpOutputBuffer,
1918+
dwReceiveDataLength + dwLocalAddressLength + dwRemoteAddressLength);
1919+
1920+
if (Status == STATUS_PENDING)
1921+
{
1922+
SetLastError(ERROR_IO_PENDING);
1923+
return FALSE;
1924+
}
1925+
else
1926+
{
1927+
if (NT_SUCCESS(Status) && lpdwBytesReceived)
1928+
*lpdwBytesReceived = IoStatusBlock->Information;
1929+
}
1930+
1931+
SetLastError(TranslateNtStatusError(Status));
1932+
1933+
return Status == STATUS_SUCCESS;
1934+
}
1935+
1936+
VOID
1937+
WSPAPI
1938+
WSPGetAcceptExSockaddrs(
1939+
IN PVOID lpOutputBuffer,
1940+
IN DWORD dwReceiveDataLength,
1941+
IN DWORD dwLocalAddressLength,
1942+
IN DWORD dwRemoteAddressLength,
1943+
OUT struct sockaddr **LocalSockaddr,
1944+
OUT LPINT LocalSockaddrLength,
1945+
OUT struct sockaddr **RemoteSockaddr,
1946+
OUT LPINT RemoteSockaddrLength)
1947+
{
1948+
/* AFD_SUPER_ACCEPT outputs recieve data + local address + local address length + remote address + remote address length */
1949+
if (dwLocalAddressLength)
1950+
{
1951+
*LocalSockaddr = (struct sockaddr*)((BYTE*)lpOutputBuffer + dwReceiveDataLength);
1952+
*LocalSockaddrLength = *(UINT*)((BYTE*)LocalSockaddr + dwLocalAddressLength - 2);
1953+
}
1954+
1955+
if (dwRemoteAddressLength)
1956+
{
1957+
*RemoteSockaddr = (struct sockaddr*)((BYTE*)lpOutputBuffer + dwReceiveDataLength + dwLocalAddressLength);
1958+
*RemoteSockaddrLength = *(UINT*)((BYTE*)RemoteSockaddr + dwRemoteAddressLength - 2);
1959+
}
1960+
}
1961+
18451962
static
18461963
VOID
18471964
NTAPI
@@ -2722,12 +2839,7 @@ WSPIoctl(IN SOCKET Handle,
27222839
*((PVOID *)lpvOutBuffer) = WSPGetAcceptExSockaddrs;
27232840
cbRet = sizeof(PVOID);
27242841
Errno = NO_ERROR;
2725-
/* See CORE-14966 and associated commits.
2726-
* Original line below was 'Ret = NO_ERROR:'.
2727-
* This caused winetest ws2_32:sock to hang.
2728-
* This new Ret value allows the test to complete. */
2729-
ERR("SIO_GET_EXTENSION_FUNCTION_POINTER UNIMPLEMENTED\n");
2730-
Ret = SOCKET_ERROR;
2842+
Ret = NO_ERROR;
27312843
}
27322844
else
27332845
{
@@ -2929,7 +3041,10 @@ WSPGetSockOpt(IN SOCKET Handle,
29293041
break;
29303042

29313043
case SO_CONNECT_TIME:
2932-
DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
3044+
if (Socket->SharedData->ConnectTime)
3045+
DwordBuffer = GetCurrentTimeInSeconds() - Socket->SharedData->ConnectTime;
3046+
else
3047+
DwordBuffer = -1;
29333048
Buffer = &DwordBuffer;
29343049
BufferSize = sizeof(DWORD);
29353050
break;
@@ -3236,6 +3351,7 @@ WSPSetSockOpt(
32363351
return NO_ERROR;
32373352

32383353
case SO_UPDATE_CONNECT_CONTEXT:
3354+
case SO_UPDATE_ACCEPT_CONTEXT:
32393355
return MsafdUpdateConnectionContext(s, lpErrno);
32403356

32413357
case SO_ERROR:

dll/win32/msafd/misc/stubs.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,6 @@ WSPJoinLeaf(
5353
return (SOCKET)0;
5454
}
5555

56-
BOOL
57-
WSPAPI
58-
WSPAcceptEx(
59-
IN SOCKET sListenSocket,
60-
IN SOCKET sAcceptSocket,
61-
OUT PVOID lpOutputBuffer,
62-
IN DWORD dwReceiveDataLength,
63-
IN DWORD dwLocalAddressLength,
64-
IN DWORD dwRemoteAddressLength,
65-
OUT LPDWORD lpdwBytesReceived,
66-
IN OUT LPOVERLAPPED lpOverlapped)
67-
{
68-
UNIMPLEMENTED;
69-
70-
return FALSE;
71-
}
72-
7356
BOOL
7457
WSPAPI
7558
WSPDisconnectEx(
@@ -83,19 +66,4 @@ WSPDisconnectEx(
8366
return FALSE;
8467
}
8568

86-
VOID
87-
WSPAPI
88-
WSPGetAcceptExSockaddrs(
89-
IN PVOID lpOutputBuffer,
90-
IN DWORD dwReceiveDataLength,
91-
IN DWORD dwLocalAddressLength,
92-
IN DWORD dwRemoteAddressLength,
93-
OUT struct sockaddr **LocalSockaddr,
94-
OUT LPINT LocalSockaddrLength,
95-
OUT struct sockaddr **RemoteSockaddr,
96-
OUT LPINT RemoteSockaddrLength)
97-
{
98-
UNIMPLEMENTED;
99-
}
100-
10169
/* EOF */

drivers/network/afd/afd/bind.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
8989
if( !(BindReq = LockRequest( Irp, IrpSp, FALSE, NULL )) )
9090
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
9191
Irp, 0 );
92+
93+
/* Cannot bind to a socket created by accept() */
94+
if (FCB->Acceptor)
95+
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
9296

9397
if (FCB->LocalAddress)
9498
{

drivers/network/afd/afd/connect.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ WarmSocketForConnection(PAFD_FCB FCB) {
256256
}
257257

258258
NTSTATUS
259-
MakeSocketIntoConnection(PAFD_FCB FCB) {
260-
NTSTATUS Status;
259+
MakeSocketIntoConnection(PAFD_FCB FCB, BOOL Recieve) {
260+
NTSTATUS Status = STATUS_SUCCESS;
261261

262262
ASSERT(!FCB->Recv.Window);
263263
ASSERT(!FCB->Send.Window);
@@ -300,15 +300,18 @@ MakeSocketIntoConnection(PAFD_FCB FCB) {
300300
FCB->SharedData.State = SOCKET_STATE_CONNECTED;
301301
FCB->SharedData.ConnectTime = 0; // Not used
302302

303-
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
304-
FCB->Connection.Object,
305-
TDI_RECEIVE_NORMAL,
306-
FCB->Recv.Window,
307-
FCB->Recv.Size,
308-
ReceiveComplete,
309-
FCB );
310-
311-
if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
303+
if (Recieve)
304+
{
305+
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
306+
FCB->Connection.Object,
307+
TDI_RECEIVE_NORMAL,
308+
FCB->Recv.Window,
309+
FCB->Recv.Size,
310+
ReceiveComplete,
311+
FCB );
312+
313+
if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
314+
}
312315

313316
FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND;
314317
FCB->PollStatus[FD_CONNECT_BIT] = STATUS_SUCCESS;
@@ -436,7 +439,7 @@ StreamSocketConnectComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp,
436439
}
437440

438441
if( NT_SUCCESS(Status) ) {
439-
Status = MakeSocketIntoConnection( FCB );
442+
Status = MakeSocketIntoConnection(FCB, TRUE);
440443

441444
if( !NT_SUCCESS(Status) ) {
442445
goto end;
@@ -557,10 +560,14 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
557560
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
558561
}
559562

563+
/* Cannot connect to a socket created by accept() */
564+
if (FCB->Acceptor)
565+
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
566+
560567
switch(FCB->SharedData.State)
561568
{
562569
case SOCKET_STATE_CONNECTED:
563-
Status = STATUS_SUCCESS;
570+
Status = STATUS_INVALID_PARAMETER;
564571
break;
565572

566573
case SOCKET_STATE_CONNECTING:

0 commit comments

Comments
 (0)