Skip to content

Commit c5c0e59

Browse files
[MSAFD][AFD] Implement WSPConnectEx and SO_UPDATE_CONNECT_CONTEXT (reactos#8636)
- Update AFD to use the shared structure - Fix AFD get context to match windows behavior - implement SO_UPDATE_CONNECT_CONTEXT CORE-17174 CORE-16335
1 parent b2c1dd8 commit c5c0e59

14 files changed

Lines changed: 599 additions & 122 deletions

File tree

dll/win32/msafd/misc/dllmain.c

Lines changed: 220 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ WSPBind(SOCKET Handle,
868868
NTSTATUS Status;
869869
SOCKADDR_INFO SocketInfo;
870870
HANDLE SockEvent;
871+
ULONG connectSize;
871872

872873
/* Get the Socket Structure associate to this Socket*/
873874
Socket = GetSocketStructure(Handle);
@@ -909,8 +910,10 @@ WSPBind(SOCKET Handle,
909910
return SOCKET_ERROR;
910911
}
911912

913+
connectSize = FIELD_OFFSET(AFD_BIND_DATA, Address.Address[SocketAddressLength]);
914+
912915
/* See below */
913-
BindData = HeapAlloc(GlobalHeap, 0, 0xA + SocketAddressLength);
916+
BindData = HeapAlloc(GlobalHeap, 0, connectSize);
914917
if (!BindData)
915918
{
916919
return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, NULL);
@@ -950,9 +953,9 @@ WSPBind(SOCKET Handle,
950953
&IOSB,
951954
IOCTL_AFD_BIND,
952955
BindData,
953-
0xA + Socket->SharedData->SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
956+
connectSize,
954957
BindData,
955-
0xA + Socket->SharedData->SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
958+
connectSize);
956959

957960
/* Wait for return */
958961
if (Status == STATUS_PENDING)
@@ -2173,6 +2176,106 @@ WSPConnect(SOCKET Handle,
21732176

21742177
return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
21752178
}
2179+
2180+
BOOL
2181+
WSPAPI
2182+
WSPConnectEx(
2183+
_In_ SOCKET Handle,
2184+
_In_ const struct sockaddr *SocketAddress,
2185+
_In_ int SocketAddressLength,
2186+
_In_ PVOID lpSendBuffer,
2187+
_In_ DWORD dwSendDataLength,
2188+
_Out_ LPDWORD lpdwBytesSent,
2189+
_Inout_ LPOVERLAPPED lpOverlapped)
2190+
{
2191+
IO_STATUS_BLOCK DummyIOSB;
2192+
PIO_STATUS_BLOCK IOSB = &DummyIOSB;
2193+
PAFD_SUPER_CONNECT_INFO ConnectInfo = NULL;
2194+
PSOCKET_INFORMATION Socket;
2195+
NTSTATUS Status;
2196+
int SocketDataLength;
2197+
UCHAR Buffer[128];
2198+
2199+
if (!lpOverlapped)
2200+
{
2201+
SetLastError(ERROR_INVALID_PARAMETER);
2202+
return FALSE;
2203+
}
2204+
2205+
if (!lpSendBuffer && dwSendDataLength)
2206+
{
2207+
SetLastError(ERROR_INVALID_PARAMETER);
2208+
return FALSE;
2209+
}
2210+
2211+
/* Get the Socket Structure associate to this Socket*/
2212+
Socket = GetSocketStructure(Handle);
2213+
if (!Socket)
2214+
{
2215+
SetLastError(WSAENOTSOCK);
2216+
return FALSE;
2217+
}
2218+
2219+
2220+
/* Cannot call on connectionless socket */
2221+
if (SocketAddressLength > ARRAYSIZE(Buffer) - sizeof(AFD_CONNECT_INFO) || Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS)
2222+
{
2223+
SetLastError(WSAEFAULT);
2224+
return SOCKET_ERROR;
2225+
}
2226+
2227+
if (Socket->SharedData->State == SocketOpen)
2228+
{
2229+
/* Socket already must be bound */
2230+
SetLastError(WSAEINVAL);
2231+
return FALSE;
2232+
}
2233+
2234+
ConnectInfo = (PAFD_SUPER_CONNECT_INFO)Buffer;
2235+
ConnectInfo->SanActive = FALSE;
2236+
2237+
/* Calculate the size of SocketAddress->sa_data */
2238+
SocketDataLength = SocketAddressLength - FIELD_OFFSET(struct sockaddr, sa_data);
2239+
2240+
/* Set up Address in TDI Format */
2241+
ConnectInfo->RemoteAddress.TAAddressCount = 1;
2242+
ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketDataLength;
2243+
ConnectInfo->RemoteAddress.Address[0].AddressType = SocketAddress->sa_family;
2244+
RtlCopyMemory(ConnectInfo->RemoteAddress.Address[0].Address,
2245+
SocketAddress->sa_data,
2246+
SocketDataLength);
2247+
2248+
/*
2249+
* Disable FD_WRITE and FD_CONNECT.
2250+
* The latter fixes a race condition where the FD_CONNECT is re-enabled
2251+
* at the end of this function right after the Async Thread disables it.
2252+
* This should only happen at the *next* WSPConnect.
2253+
*/
2254+
if (Socket->SharedData->AsyncEvents & FD_CONNECT)
2255+
{
2256+
Socket->SharedData->AsyncDisabledEvents |= (FD_CONNECT | FD_WRITE);
2257+
}
2258+
2259+
IOSB = (PIO_STATUS_BLOCK)lpOverlapped;
2260+
IOSB->Status = STATUS_PENDING;
2261+
2262+
/* Send IOCTL */
2263+
Status = NtDeviceIoControlFile((HANDLE)Handle,
2264+
lpOverlapped->hEvent,
2265+
NULL,
2266+
lpOverlapped->hEvent ? NULL : lpOverlapped,
2267+
IOSB,
2268+
IOCTL_AFD_SUPER_CONNECT,
2269+
ConnectInfo,
2270+
FIELD_OFFSET(AFD_SUPER_CONNECT_INFO, RemoteAddress.Address[0].Address[SocketDataLength]),
2271+
lpSendBuffer,
2272+
dwSendDataLength);
2273+
2274+
SetLastError(TranslateNtStatusError(Status));
2275+
2276+
return Status == STATUS_SUCCESS;
2277+
}
2278+
21762279
int
21772280
WSPAPI
21782281
WSPShutdown(SOCKET Handle,
@@ -2882,6 +2985,116 @@ WSPGetSockOpt(IN SOCKET Handle,
28822985
return (Errno == NO_ERROR) ? NO_ERROR : SOCKET_ERROR;
28832986
}
28842987

2988+
static
2989+
INT
2990+
NTAPI
2991+
MsafdUpdateConnectionContext(
2992+
_In_ SOCKET Handle,
2993+
_Out_ LPINT lpErrno)
2994+
{
2995+
IO_STATUS_BLOCK DummyIOSB;
2996+
PIO_STATUS_BLOCK IOSB = &DummyIOSB;
2997+
NTSTATUS Status;
2998+
SOCK_SHARED_INFO SharedData;
2999+
AFD_TDI_HANDLE_DATA HandleData;
3000+
HANDLE SockEvent;
3001+
PSOCKET_INFORMATION Socket = GetSocketStructure(Handle);
3002+
3003+
if (!Socket)
3004+
{
3005+
if (lpErrno) *lpErrno = WSAENOTSOCK;
3006+
return SOCKET_ERROR;
3007+
}
3008+
3009+
if (Socket->SharedData->State == SocketConnected)
3010+
{
3011+
return NO_ERROR;
3012+
}
3013+
3014+
/* Get the socket context from AFD because when ConnectEx is used, this information is not updated. */
3015+
Status = NtCreateEvent(&SockEvent,
3016+
EVENT_ALL_ACCESS,
3017+
NULL,
3018+
SynchronizationEvent,
3019+
FALSE);
3020+
if (!NT_SUCCESS(Status))
3021+
goto Quit;
3022+
3023+
Status = NtDeviceIoControlFile((HANDLE)Handle,
3024+
SockEvent,
3025+
NULL,
3026+
NULL,
3027+
IOSB,
3028+
IOCTL_AFD_GET_CONTEXT,
3029+
NULL,
3030+
0,
3031+
&SharedData,
3032+
sizeof(SharedData));
3033+
3034+
if (Status == STATUS_PENDING)
3035+
{
3036+
MsafdWaitForAlert(SockEvent);
3037+
Status = IOSB->Status;
3038+
}
3039+
3040+
if (!NT_SUCCESS(Status))
3041+
goto Quit;
3042+
3043+
ULONG flags = AFD_CONNECTION_HANDLE | AFD_ADDRESS_HANDLE;
3044+
3045+
/* Get TDI handles from AFD */
3046+
Status = NtDeviceIoControlFile((HANDLE)Handle,
3047+
SockEvent,
3048+
NULL,
3049+
NULL,
3050+
IOSB,
3051+
IOCTL_AFD_GET_TDI_HANDLES,
3052+
&flags,
3053+
sizeof(flags),
3054+
&HandleData,
3055+
sizeof(HandleData));
3056+
3057+
if (Status == STATUS_PENDING)
3058+
{
3059+
MsafdWaitForAlert(SockEvent);
3060+
Status = IOSB->Status;
3061+
}
3062+
3063+
/* Bail out if the socket was destroyed */
3064+
if (!NT_SUCCESS(Status))
3065+
goto Quit;
3066+
3067+
Socket->SharedData->State = SharedData.State;
3068+
3069+
if (SharedData.State == SocketConnected)
3070+
{
3071+
/* Socket is now connected, update usermode msafd socket structure, same as the end of WSPConnect */
3072+
Socket->TdiConnectionHandle = HandleData.TdiConnectionHandle;
3073+
Socket->TdiAddressHandle = HandleData.TdiAddressHandle;
3074+
Socket->SharedData->ConnectTime = SharedData.ConnectTime;
3075+
3076+
/* Re-enable Async Event */
3077+
SockReenableAsyncSelectEvent(Socket, FD_WRITE);
3078+
3079+
/* FIXME: THIS IS NOT RIGHT!!! HACK HACK HACK! */
3080+
SockReenableAsyncSelectEvent(Socket, FD_CONNECT);
3081+
3082+
Socket->HelperData->WSHNotify(Socket->HelperContext,
3083+
Socket->Handle,
3084+
Socket->TdiAddressHandle,
3085+
Socket->TdiConnectionHandle,
3086+
WSH_NOTIFY_CONNECT);
3087+
}
3088+
3089+
NtClose(SockEvent);
3090+
3091+
Quit:
3092+
if (Status == STATUS_SUCCESS)
3093+
return NO_ERROR;
3094+
if (lpErrno) *lpErrno = TranslateNtStatusError(Status);
3095+
return SOCKET_ERROR;
3096+
}
3097+
28853098
INT
28863099
WSPAPI
28873100
WSPSetSockOpt(
@@ -2902,7 +3115,7 @@ WSPSetSockOpt(
29023115
if (lpErrno) *lpErrno = WSAENOTSOCK;
29033116
return SOCKET_ERROR;
29043117
}
2905-
if (!optval)
3118+
if (!optval && optlen)
29063119
{
29073120
if (lpErrno) *lpErrno = WSAEFAULT;
29083121
return SOCKET_ERROR;
@@ -3022,6 +3235,9 @@ WSPSetSockOpt(
30223235

30233236
return NO_ERROR;
30243237

3238+
case SO_UPDATE_CONNECT_CONTEXT:
3239+
return MsafdUpdateConnectionContext(s, lpErrno);
3240+
30253241
case SO_ERROR:
30263242
if (optlen < sizeof(INT))
30273243
{

dll/win32/msafd/misc/stubs.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,6 @@ WSPAcceptEx(
7070
return FALSE;
7171
}
7272

73-
BOOL
74-
WSPAPI
75-
WSPConnectEx(
76-
IN SOCKET s,
77-
IN const struct sockaddr *name,
78-
IN int namelen,
79-
IN PVOID lpSendBuffer,
80-
IN DWORD dwSendDataLength,
81-
OUT LPDWORD lpdwBytesSent,
82-
IN OUT LPOVERLAPPED lpOverlapped)
83-
{
84-
UNIMPLEMENTED;
85-
86-
return FALSE;
87-
}
88-
8973
BOOL
9074
WSPAPI
9175
WSPDisconnectEx(

dll/win32/msafd/msafd.h

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -42,59 +42,6 @@ extern HANDLE SockEvent;
4242
extern HANDLE SockAsyncCompletionPort;
4343
extern BOOLEAN SockAsyncSelectCalled;
4444

45-
typedef enum _SOCKET_STATE {
46-
SocketOpen,
47-
SocketBound,
48-
SocketBoundUdp,
49-
SocketConnected,
50-
SocketClosed
51-
} SOCKET_STATE, *PSOCKET_STATE;
52-
53-
typedef struct _SOCK_SHARED_INFO {
54-
SOCKET_STATE State;
55-
LONG RefCount;
56-
INT AddressFamily;
57-
INT SocketType;
58-
INT Protocol;
59-
INT SizeOfLocalAddress;
60-
INT SizeOfRemoteAddress;
61-
struct linger LingerData;
62-
ULONG SendTimeout;
63-
ULONG RecvTimeout;
64-
ULONG SizeOfRecvBuffer;
65-
ULONG SizeOfSendBuffer;
66-
ULONG ConnectTime;
67-
struct {
68-
BOOLEAN Listening:1;
69-
BOOLEAN Broadcast:1;
70-
BOOLEAN Debug:1;
71-
BOOLEAN OobInline:1;
72-
BOOLEAN ReuseAddresses:1;
73-
BOOLEAN ExclusiveAddressUse:1;
74-
BOOLEAN NonBlocking:1;
75-
BOOLEAN DontUseWildcard:1;
76-
BOOLEAN ReceiveShutdown:1;
77-
BOOLEAN SendShutdown:1;
78-
BOOLEAN UseDelayedAcceptance:1;
79-
BOOLEAN UseSAN:1;
80-
}; // Flags
81-
DWORD CreateFlags;
82-
DWORD ServiceFlags1;
83-
DWORD ProviderFlags;
84-
GROUP GroupID;
85-
DWORD GroupType;
86-
INT GroupPriority;
87-
INT SocketLastError;
88-
HWND hWnd;
89-
LONG Unknown;
90-
DWORD SequenceNumber;
91-
UINT wMsg;
92-
LONG AsyncEvents;
93-
LONG AsyncDisabledEvents;
94-
SOCKADDR WSLocalAddress;
95-
SOCKADDR WSRemoteAddress;
96-
} SOCK_SHARED_INFO, *PSOCK_SHARED_INFO;
97-
9845
typedef struct _SOCKET_INFORMATION {
9946
SOCKET Handle;
10047
PSOCK_SHARED_INFO SharedData;

drivers/network/afd/afd/bind.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
115115
Irp->RequestorMode,
116116
&UserHandle);
117117
if (NT_SUCCESS(Status))
118-
FCB->State = SOCKET_STATE_BOUND;
118+
FCB->SharedData.State = SOCKET_STATE_BOUND;
119119
}
120120

121121
/* MSAFD relies on us returning the address file handle in the IOSB */

0 commit comments

Comments
 (0)