@@ -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+
18451962static
18461963VOID
18471964NTAPI
@@ -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 :
0 commit comments