ReactOS  0.4.14-dev-55-g2da92ac
sndrcv.c File Reference
#include <msafd.h>
Include dependency graph for sndrcv.c:

Go to the source code of this file.

Functions

INT WSPAPI WSPAsyncSelect (IN SOCKET Handle, IN HWND hWnd, IN UINT wMsg, IN LONG lEvent, OUT LPINT lpErrno)
 
BOOL WSPAPI WSPGetOverlappedResult (IN SOCKET Handle, IN LPWSAOVERLAPPED lpOverlapped, OUT LPDWORD lpdwBytes, IN BOOL fWait, OUT LPDWORD lpdwFlags, OUT LPINT lpErrno)
 
VOID NTAPI AfdAPC (PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
 
int WSPAPI WSPRecv (SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
 
int WSPAPI WSPRecvFrom (SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, struct sockaddr *SocketAddress, int *SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
 
int WSPAPI WSPSend (SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
 
int WSPAPI WSPSendTo (SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, const struct sockaddr *SocketAddress, int SocketAddressLength, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
 
INT WSPAPI WSPRecvDisconnect (IN SOCKET s, OUT LPWSABUF lpInboundDisconnectData, OUT LPINT lpErrno)
 
INT WSPAPI WSPSendDisconnect (IN SOCKET s, IN LPWSABUF lpOutboundDisconnectData, OUT LPINT lpErrno)
 

Function Documentation

◆ AfdAPC()

VOID NTAPI AfdAPC ( PVOID  ApcContext,
PIO_STATUS_BLOCK  IoStatusBlock,
ULONG  Reserved 
)

Definition at line 140 of file sndrcv.c.

143 {
145 
146  /* Re-enable Async Event */
150 
151  Context->lpCompletionRoutine(IoStatusBlock->Status, IoStatusBlock->Information, Context->lpOverlapped, 0);
153 }
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3983
#define FD_READ
Definition: winsock.h:405
#define FD_OOB
Definition: winsock.h:407
#define FD_WRITE
Definition: winsock.h:406
HANDLE GlobalHeap
Definition: dllmain.c:19
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by WSPRecv(), WSPRecvFrom(), WSPSend(), and WSPSendTo().

◆ WSPAsyncSelect()

INT WSPAPI WSPAsyncSelect ( IN SOCKET  Handle,
IN HWND  hWnd,
IN UINT  wMsg,
IN LONG  lEvent,
OUT LPINT  lpErrno 
)

Definition at line 17 of file sndrcv.c.

22 {
23  PSOCKET_INFORMATION Socket = NULL;
24  PASYNC_DATA AsyncData;
25  BOOLEAN BlockMode;
26 
27  /* Get the Socket Structure associated to this Socket */
28  Socket = GetSocketStructure(Handle);
29  if (!Socket)
30  {
31  *lpErrno = WSAENOTSOCK;
32  return SOCKET_ERROR;
33  }
34 
35  /* Allocate the Async Data Structure to pass on to the Thread later */
36  AsyncData = HeapAlloc(GetProcessHeap(), 0, sizeof(*AsyncData));
37  if (!AsyncData)
38  {
40  return INVALID_SOCKET;
41  }
42 
43  /* Change the Socket to Non Blocking */
44  BlockMode = TRUE;
46  Socket->SharedData->NonBlocking = TRUE;
47 
48  /* Deactivate WSPEventSelect */
49  if (Socket->SharedData->AsyncEvents)
50  {
51  if (WSPEventSelect(Handle, NULL, 0, lpErrno) == SOCKET_ERROR)
52  {
53  HeapFree(GetProcessHeap(), 0, AsyncData);
54  return SOCKET_ERROR;
55  }
56  }
57 
58  /* Create the Asynch Thread if Needed */
60 
61  /* Open a Handle to AFD's Async Helper */
63 
64  /* Store Socket Data */
65  Socket->SharedData->hWnd = hWnd;
66  Socket->SharedData->wMsg = wMsg;
67  Socket->SharedData->AsyncEvents = lEvent;
68  Socket->SharedData->AsyncDisabledEvents = 0;
69  Socket->SharedData->SequenceNumber++;
70 
71  /* Return if there are no more Events */
72  if ((Socket->SharedData->AsyncEvents & (~Socket->SharedData->AsyncDisabledEvents)) == 0)
73  {
74  HeapFree(GetProcessHeap(), 0, AsyncData);
75  return 0;
76  }
77 
78  /* Set up the Async Data */
79  AsyncData->ParentSocket = Socket;
80  AsyncData->SequenceNumber = Socket->SharedData->SequenceNumber;
81 
82  /* Begin Async Select by using I/O Completion */
85  AsyncData,
86  0,
87  0);
88 
89  /* Return */
90  return ERROR_SUCCESS;
91 }
#define WSAENOTSOCK
Definition: winerror.h:1951
#define SOCKET_ERROR
Definition: winsock.h:333
DWORD SequenceNumber
Definition: msafd.h:131
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
Definition: dllmain.c:3675
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3507
HANDLE SockAsyncCompletionPort
Definition: dllmain.c:28
HWND hWnd
Definition: settings.c:17
DWORD SequenceNumber
Definition: msafd.h:90
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
Definition: dllmain.c:3580
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3949
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define AFD_INFO_BLOCKING_MODE
Definition: shared.h:183
BOOLEAN NonBlocking
Definition: msafd.h:74
_In_ HANDLE Handle
Definition: extypes.h:390
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define INVALID_SOCKET
Definition: winsock.h:332
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:568
PSOCKET_INFORMATION ParentSocket
Definition: msafd.h:130
int WSPAPI WSPEventSelect(IN SOCKET Handle, IN WSAEVENT hEventObject, IN long lNetworkEvents, OUT LPINT lpErrno)
Definition: event.c:17
HANDLE lEvent
Definition: tftpd.cpp:56
int SetSocketInformation(PSOCKET_INFORMATION Socket, ULONG AfdInformationClass, PBOOLEAN Boolean OPTIONAL, PULONG Ulong OPTIONAL, PLARGE_INTEGER LargeInteger OPTIONAL, LPWSAOVERLAPPED Overlapped OPTIONAL, LPWSAOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine OPTIONAL)
Definition: dllmain.c:3384
LONG AsyncDisabledEvents
Definition: msafd.h:93
LONG AsyncEvents
Definition: msafd.h:92
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by WSPStartup().

◆ WSPGetOverlappedResult()

BOOL WSPAPI WSPGetOverlappedResult ( IN SOCKET  Handle,
IN LPWSAOVERLAPPED  lpOverlapped,
OUT LPDWORD  lpdwBytes,
IN BOOL  fWait,
OUT LPDWORD  lpdwFlags,
OUT LPINT  lpErrno 
)

Definition at line 96 of file sndrcv.c.

103 {
104  PSOCKET_INFORMATION Socket;
105  BOOL Ret;
106 
107  TRACE("Called (%x)\n", Handle);
108 
109  /* Get the Socket Structure associate to this Socket*/
110  Socket = GetSocketStructure(Handle);
111  if (!Socket)
112  {
113  if(lpErrno)
114  *lpErrno = WSAENOTSOCK;
115  return FALSE;
116  }
117  if (!lpOverlapped || !lpdwBytes || !lpdwFlags)
118  {
119  if (lpErrno)
120  *lpErrno = WSAEFAULT;
121  return FALSE;
122  }
123  Ret = GetOverlappedResult((HANDLE)Handle, lpOverlapped, lpdwBytes, fWait);
124 
125  if (Ret)
126  {
127  *lpdwFlags = 0;
128 
129  /* Re-enable Async Event */
133  }
134 
135  return Ret;
136 }
#define WSAENOTSOCK
Definition: winerror.h:1951
#define WSAEFAULT
Definition: winerror.h:1945
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3983
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3507
#define FD_READ
Definition: winsock.h:405
#define FD_OOB
Definition: winsock.h:407
#define FD_WRITE
Definition: winsock.h:406
unsigned int BOOL
Definition: ntddk_ex.h:94
_In_ HANDLE Handle
Definition: extypes.h:390
#define TRACE(s)
Definition: solgame.cpp:4
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90

Referenced by WSPStartup().

◆ WSPRecv()

int WSPAPI WSPRecv ( SOCKET  Handle,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesRead,
LPDWORD  ReceiveFlags,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 157 of file sndrcv.c.

166 {
167  PIO_STATUS_BLOCK IOSB;
168  IO_STATUS_BLOCK DummyIOSB;
169  AFD_RECV_INFO RecvInfo;
171  PVOID APCContext;
172  PIO_APC_ROUTINE APCFunction;
173  HANDLE Event = NULL;
175  PSOCKET_INFORMATION Socket;
176 
177  TRACE("Called (%x)\n", Handle);
178 
179  /* Get the Socket Structure associate to this Socket*/
180  Socket = GetSocketStructure(Handle);
181  if (!Socket)
182  {
183  if (lpErrno)
184  *lpErrno = WSAENOTSOCK;
185  return SOCKET_ERROR;
186  }
187  if (!lpNumberOfBytesRead && !lpOverlapped)
188  {
189  if (lpErrno)
190  *lpErrno = WSAEFAULT;
191  return SOCKET_ERROR;
192  }
193  if (Socket->SharedData->OobInline && ReceiveFlags && (*ReceiveFlags & MSG_OOB) != 0)
194  {
195  if (lpErrno)
196  *lpErrno = WSAEINVAL;
197  return SOCKET_ERROR;
198  }
199 
202 
203  if( !NT_SUCCESS(Status) )
204  return -1;
205 
206  /* Set up the Receive Structure */
207  RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
208  RecvInfo.BufferCount = dwBufferCount;
209  RecvInfo.TdiFlags = 0;
210  RecvInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
211 
212  /* Set the TDI Flags */
213  if (*ReceiveFlags == 0)
214  {
215  RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
216  }
217  else
218  {
219  if (*ReceiveFlags & MSG_OOB)
220  {
221  RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED;
222  }
223 
224  if (*ReceiveFlags & MSG_PEEK)
225  {
226  RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK;
227  }
228 
229  if (*ReceiveFlags & MSG_PARTIAL)
230  {
231  RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL;
232  }
233  }
234 
235  /* Verify if we should use APC */
236 
237  if (lpOverlapped == NULL)
238  {
239  /* Not using Overlapped structure, so use normal blocking on event */
240  APCContext = NULL;
241  APCFunction = NULL;
242  Event = SockEvent;
243  IOSB = &DummyIOSB;
244  }
245  else
246  {
247  /* Overlapped request for non overlapped opened socket */
248  if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
249  {
250  TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
251  return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead);
252  }
253  if (lpCompletionRoutine == NULL)
254  {
255  /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
256  APCContext = lpOverlapped;
257  APCFunction = NULL;
258  Event = lpOverlapped->hEvent;
259  }
260  else
261  {
262  /* Using Overlapped Structure and a Completion Routine, so use an APC */
263  APCFunction = &AfdAPC; // should be a private io completion function inside us
264  APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
265  if (!APCContext)
266  {
267  ERR("Not enough memory for APC Context\n");
268  return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead);
269  }
270  ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
271  ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
272  ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
273  RecvInfo.AfdFlags |= AFD_SKIP_FIO;
274  }
275 
276  IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
277  RecvInfo.AfdFlags |= AFD_OVERLAPPED;
278  }
279 
280  IOSB->Status = STATUS_PENDING;
281 
282  /* Send IOCTL */
284  Event,
285  APCFunction,
286  APCContext,
287  IOSB,
289  &RecvInfo,
290  sizeof(RecvInfo),
291  NULL,
292  0);
293 
294  /* Wait for completion of not overlapped */
295  if (Status == STATUS_PENDING && lpOverlapped == NULL)
296  {
297  /* It's up to the protocol to time out recv. We must wait
298  * until the protocol decides it's had enough.
299  */
301  Status = IOSB->Status;
302  }
303 
304  NtClose( SockEvent );
305 
306  TRACE("Status %x Information %d\n", Status, IOSB->Information);
307 
308  if (Status == STATUS_PENDING)
309  {
310  TRACE("Leaving (Pending)\n");
311  return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead);
312  }
313 
314  /* Return the Flags */
315  *ReceiveFlags = 0;
316 
317  switch (Status)
318  {
320  *ReceiveFlags = MSG_OOB;
321  break;
323  *ReceiveFlags = MSG_PARTIAL | MSG_OOB;
324  break;
326  *ReceiveFlags = MSG_PARTIAL;
327  break;
328  }
329 
330  /* Re-enable Async Event */
331  if (*ReceiveFlags & MSG_OOB)
332  {
334  }
335  else
336  {
338  }
339 
340  if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
341  {
342  lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags);
343  HeapFree(GlobalHeap, 0, (PVOID)APCContext);
344  }
345 
346  return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
347 }
#define WSAENOTSOCK
Definition: winerror.h:1951
#define SOCKET_ERROR
Definition: winsock.h:333
#define STATUS_RECEIVE_PARTIAL
Definition: ntstatus.h:129
HANDLE SockEvent
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WSAEFAULT
Definition: winerror.h:1945
#define TDI_RECEIVE_PARTIAL
Definition: tdi.h:121
#define AFD_IMMEDIATE
Definition: shared.h:220
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3983
#define WSAEINVAL
Definition: winerror.h:1946
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3507
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN OobInline
Definition: msafd.h:71
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:100
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
ULONG AfdFlags
Definition: shared.h:87
#define FD_READ
Definition: winsock.h:405
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define TDI_RECEIVE_EXPEDITED
Definition: tdi.h:123
VOID NTAPI AfdAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: sndrcv.c:140
#define FD_OOB
Definition: winsock.h:407
DWORD CreateFlags
Definition: msafd.h:81
#define AFD_SKIP_FIO
Definition: shared.h:218
#define TDI_RECEIVE_NORMAL
Definition: tdi.h:122
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define MSG_OOB
Definition: winsock.h:221
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN NonBlocking
Definition: msafd.h:74
_In_ HANDLE Handle
Definition: extypes.h:390
#define AFD_OVERLAPPED
Definition: shared.h:219
#define TRACE(s)
Definition: solgame.cpp:4
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
#define STATUS_RECEIVE_EXPEDITED
Definition: ntstatus.h:130
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
PAFD_WSABUF BufferArray
Definition: shared.h:85
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define MSG_PARTIAL
Definition: winsock.h:402
ULONG TdiFlags
Definition: shared.h:88
ULONG BufferCount
Definition: shared.h:86
#define IOCTL_AFD_RECV
Definition: shared.h:277
struct _AFD_WSABUF * PAFD_WSABUF
HANDLE GlobalHeap
Definition: dllmain.c:19
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
#define TDI_RECEIVE_PEEK
Definition: tdi.h:124
#define STATUS_RECEIVE_PARTIAL_EXPEDITED
Definition: ntstatus.h:131
#define INFINITE
Definition: serial.h:102
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define HeapFree(x, y, z)
Definition: compat.h:394
#define MSG_PEEK
Definition: winsock.h:222

Referenced by WSPRecvFrom(), and WSPStartup().

◆ WSPRecvDisconnect()

INT WSPAPI WSPRecvDisconnect ( IN SOCKET  s,
OUT LPWSABUF  lpInboundDisconnectData,
OUT LPINT  lpErrno 
)

Definition at line 919 of file sndrcv.c.

922 {
924  return 0;
925 }
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by WSPStartup().

◆ WSPRecvFrom()

int WSPAPI WSPRecvFrom ( SOCKET  Handle,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesRead,
LPDWORD  ReceiveFlags,
struct sockaddr SocketAddress,
int SocketAddressLength,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 351 of file sndrcv.c.

362 {
363  PIO_STATUS_BLOCK IOSB;
364  IO_STATUS_BLOCK DummyIOSB;
365  AFD_RECV_INFO_UDP RecvInfo;
367  PVOID APCContext;
368  PVOID APCFunction;
369  HANDLE Event = NULL;
371  PSOCKET_INFORMATION Socket;
372 
373  /* Get the Socket Structure associate to this Socket*/
374  Socket = GetSocketStructure(Handle);
375  if (!Socket)
376  {
377  if (lpErrno)
378  *lpErrno = WSAENOTSOCK;
379  return SOCKET_ERROR;
380  }
381  if (!lpNumberOfBytesRead && !lpOverlapped)
382  {
383  if (lpErrno)
384  *lpErrno = WSAEFAULT;
385  return SOCKET_ERROR;
386  }
387  if (Socket->SharedData->OobInline && ReceiveFlags && (*ReceiveFlags & MSG_OOB) != 0)
388  {
389  if (lpErrno)
390  *lpErrno = WSAEINVAL;
391  return SOCKET_ERROR;
392  }
393 
394  if (!(Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS))
395  {
396  /* Call WSPRecv for a non-datagram socket */
397  return WSPRecv(Handle,
398  lpBuffers,
399  dwBufferCount,
400  lpNumberOfBytesRead,
401  ReceiveFlags,
402  lpOverlapped,
403  lpCompletionRoutine,
404  lpThreadId,
405  lpErrno);
406  }
407 
408  /* Bind us First */
409  if (Socket->SharedData->State == SocketOpen)
410  {
412  SocketAddress,
413  SocketAddressLength);
414  /* Bind it */
415  if (WSPBind(Handle, SocketAddress, *SocketAddressLength, lpErrno) == SOCKET_ERROR)
416  return SOCKET_ERROR;
417  }
418 
421 
422  if( !NT_SUCCESS(Status) )
423  return -1;
424 
425  /* Set up the Receive Structure */
426  RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
427  RecvInfo.BufferCount = dwBufferCount;
428  RecvInfo.TdiFlags = 0;
429  RecvInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
430  RecvInfo.AddressLength = SocketAddressLength;
431  RecvInfo.Address = SocketAddress;
432 
433  /* Set the TDI Flags */
434  if (*ReceiveFlags == 0)
435  {
436  RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
437  }
438  else
439  {
440  if (*ReceiveFlags & MSG_OOB)
441  {
442  RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED;
443  }
444 
445  if (*ReceiveFlags & MSG_PEEK)
446  {
447  RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK;
448  }
449 
450  if (*ReceiveFlags & MSG_PARTIAL)
451  {
452  RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL;
453  }
454  }
455 
456  /* Verify if we should use APC */
457 
458  if (lpOverlapped == NULL)
459  {
460  /* Not using Overlapped structure, so use normal blocking on event */
461  APCContext = NULL;
462  APCFunction = NULL;
463  Event = SockEvent;
464  IOSB = &DummyIOSB;
465  }
466  else
467  {
468  /* Overlapped request for non overlapped opened socket */
469  if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
470  {
471  TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
472  return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead);
473  }
474  if (lpCompletionRoutine == NULL)
475  {
476  /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
477  APCContext = lpOverlapped;
478  APCFunction = NULL;
479  Event = lpOverlapped->hEvent;
480  }
481  else
482  {
483  /* Using Overlapped Structure and a Completion Routine, so use an APC */
484  APCFunction = &AfdAPC; // should be a private io completion function inside us
485  APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
486  if (!APCContext)
487  {
488  ERR("Not enough memory for APC Context\n");
489  return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead);
490  }
491  ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
492  ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
493  ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
494  RecvInfo.AfdFlags |= AFD_SKIP_FIO;
495  }
496 
497  IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
498  RecvInfo.AfdFlags |= AFD_OVERLAPPED;
499  }
500 
501  IOSB->Status = STATUS_PENDING;
502 
503  /* Send IOCTL */
505  Event,
506  APCFunction,
507  APCContext,
508  IOSB,
510  &RecvInfo,
511  sizeof(RecvInfo),
512  NULL,
513  0);
514 
515  /* Wait for completion of not overlapped */
516  if (Status == STATUS_PENDING && lpOverlapped == NULL)
517  {
518  WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for receive...
519  Status = IOSB->Status;
520  }
521 
522  NtClose( SockEvent );
523 
524  if (Status == STATUS_PENDING)
525  {
526  TRACE("Leaving (Pending)\n");
527  return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead);
528  }
529 
530  /* Return the Flags */
531  *ReceiveFlags = 0;
532 
533  switch (Status)
534  {
536  *ReceiveFlags = MSG_OOB;
537  break;
539  *ReceiveFlags = MSG_PARTIAL | MSG_OOB;
540  break;
542  *ReceiveFlags = MSG_PARTIAL;
543  break;
544  }
545 
546  /* Re-enable Async Event */
547  if (*ReceiveFlags & MSG_OOB)
548  {
550  }
551  else
552  {
554  }
555 
556  if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
557  {
558  lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags);
559  HeapFree(GlobalHeap, 0, (PVOID)APCContext);
560  }
561 
562  return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
563 }
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
#define WSAENOTSOCK
Definition: winerror.h:1951
#define SOCKET_ERROR
Definition: winsock.h:333
#define STATUS_RECEIVE_PARTIAL
Definition: ntstatus.h:129
ULONG AfdFlags
Definition: shared.h:94
HANDLE SockEvent
PINT AddressLength
Definition: shared.h:97
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WSAEFAULT
Definition: winerror.h:1945
#define TDI_RECEIVE_PARTIAL
Definition: tdi.h:121
#define AFD_IMMEDIATE
Definition: shared.h:220
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3983
#define WSAEINVAL
Definition: winerror.h:1946
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3507
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN OobInline
Definition: msafd.h:71
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:100
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
PAFD_WSABUF BufferArray
Definition: shared.h:92
#define FD_READ
Definition: winsock.h:405
#define IOCTL_AFD_RECV_DATAGRAM
Definition: shared.h:279
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define TDI_RECEIVE_EXPEDITED
Definition: tdi.h:123
VOID NTAPI AfdAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: sndrcv.c:140
#define FD_OOB
Definition: winsock.h:407
DWORD CreateFlags
Definition: msafd.h:81
int WSPAPI WSPRecv(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRead, LPDWORD ReceiveFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:157
#define AFD_SKIP_FIO
Definition: shared.h:218
#define TDI_RECEIVE_NORMAL
Definition: tdi.h:122
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define MSG_OOB
Definition: winsock.h:221
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
smooth NULL
Definition: ftsmooth.c:416
PHELPER_DATA HelperData
Definition: msafd.h:103
ULONG TdiFlags
Definition: shared.h:95
BOOLEAN NonBlocking
Definition: msafd.h:74
_In_ HANDLE Handle
Definition: extypes.h:390
#define AFD_OVERLAPPED
Definition: shared.h:219
DWORD ServiceFlags1
Definition: msafd.h:82
#define TRACE(s)
Definition: solgame.cpp:4
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
#define STATUS_RECEIVE_EXPEDITED
Definition: ntstatus.h:130
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define MSG_PARTIAL
Definition: winsock.h:402
struct _AFD_WSABUF * PAFD_WSABUF
HANDLE GlobalHeap
Definition: dllmain.c:19
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:846
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
#define XP1_CONNECTIONLESS
Definition: winsock2.h:436
#define TDI_RECEIVE_PEEK
Definition: tdi.h:124
#define STATUS_RECEIVE_PARTIAL_EXPEDITED
Definition: ntstatus.h:131
ULONG BufferCount
Definition: shared.h:93
SOCKET_STATE State
Definition: msafd.h:54
PVOID HelperContext
Definition: msafd.h:104
#define INFINITE
Definition: serial.h:102
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define HeapFree(x, y, z)
Definition: compat.h:394
#define MSG_PEEK
Definition: winsock.h:222

Referenced by WSPStartup().

◆ WSPSend()

int WSPAPI WSPSend ( SOCKET  Handle,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesSent,
DWORD  iFlags,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 568 of file sndrcv.c.

577 {
578  PIO_STATUS_BLOCK IOSB;
579  IO_STATUS_BLOCK DummyIOSB;
580  AFD_SEND_INFO SendInfo;
582  PVOID APCContext;
583  PVOID APCFunction;
584  HANDLE Event = NULL;
586  PSOCKET_INFORMATION Socket;
587 
588  /* Get the Socket Structure associate to this Socket*/
589  Socket = GetSocketStructure(Handle);
590  if (!Socket)
591  {
592  if (lpErrno)
593  *lpErrno = WSAENOTSOCK;
594  return SOCKET_ERROR;
595  }
596  if (!lpNumberOfBytesSent && !lpOverlapped)
597  {
598  if (lpErrno)
599  *lpErrno = WSAEFAULT;
600  return SOCKET_ERROR;
601  }
602 
605 
606  if( !NT_SUCCESS(Status) )
607  return -1;
608 
609  TRACE("Called\n");
610 
611  /* Set up the Send Structure */
612  SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
613  SendInfo.BufferCount = dwBufferCount;
614  SendInfo.TdiFlags = 0;
615  SendInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
616 
617  /* Set the TDI Flags */
618  if (iFlags)
619  {
620  if (iFlags & MSG_OOB)
621  {
622  SendInfo.TdiFlags |= TDI_SEND_EXPEDITED;
623  }
624  if (iFlags & MSG_PARTIAL)
625  {
626  SendInfo.TdiFlags |= TDI_SEND_PARTIAL;
627  }
628  }
629 
630  /* Verify if we should use APC */
631  if (lpOverlapped == NULL)
632  {
633  /* Not using Overlapped structure, so use normal blocking on event */
634  APCContext = NULL;
635  APCFunction = NULL;
636  Event = SockEvent;
637  IOSB = &DummyIOSB;
638  }
639  else
640  {
641  /* Overlapped request for non overlapped opened socket */
642  if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
643  {
644  TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
645  return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent);
646  }
647  if (lpCompletionRoutine == NULL)
648  {
649  /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
650  APCContext = lpOverlapped;
651  APCFunction = NULL;
652  Event = lpOverlapped->hEvent;
653  }
654  else
655  {
656  /* Using Overlapped Structure and a Completion Routine, so use an APC */
657  APCFunction = &AfdAPC; // should be a private io completion function inside us
658  APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
659  if (!APCContext)
660  {
661  ERR("Not enough memory for APC Context\n");
662  return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent);
663  }
664  ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
665  ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
666  ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
667  SendInfo.AfdFlags |= AFD_SKIP_FIO;
668  }
669 
670  IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
671  SendInfo.AfdFlags |= AFD_OVERLAPPED;
672  }
673 
674  IOSB->Status = STATUS_PENDING;
675 
676  /* Send IOCTL */
678  Event,
679  APCFunction,
680  APCContext,
681  IOSB,
683  &SendInfo,
684  sizeof(SendInfo),
685  NULL,
686  0);
687 
688  /* Wait for completion of not overlapped */
689  if (Status == STATUS_PENDING && lpOverlapped == NULL)
690  {
691  WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for send...
692  Status = IOSB->Status;
693  }
694 
695  NtClose( SockEvent );
696 
697  if (Status == STATUS_PENDING)
698  {
699  TRACE("Leaving (Pending)\n");
700  return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
701  }
702 
703  /* Re-enable Async Event */
705 
706  TRACE("Leaving (Success, %d)\n", IOSB->Information);
707 
708  if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
709  {
710  lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0);
711  HeapFree(GlobalHeap, 0, (PVOID)APCContext);
712  }
713 
714  return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
715 }
#define WSAENOTSOCK
Definition: winerror.h:1951
#define SOCKET_ERROR
Definition: winsock.h:333
HANDLE SockEvent
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WSAEFAULT
Definition: winerror.h:1945
#define AFD_IMMEDIATE
Definition: shared.h:220
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3983
ULONG TdiFlags
Definition: shared.h:104
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3507
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:100
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
VOID NTAPI AfdAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: sndrcv.c:140
DWORD CreateFlags
Definition: msafd.h:81
#define FD_WRITE
Definition: winsock.h:406
#define AFD_SKIP_FIO
Definition: shared.h:218
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define MSG_OOB
Definition: winsock.h:221
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
smooth NULL
Definition: ftsmooth.c:416
#define TDI_SEND_EXPEDITED
Definition: tdi.h:135
ULONG AfdFlags
Definition: shared.h:103
ULONG BufferCount
Definition: shared.h:102
BOOLEAN NonBlocking
Definition: msafd.h:74
_In_ HANDLE Handle
Definition: extypes.h:390
#define AFD_OVERLAPPED
Definition: shared.h:219
#define TRACE(s)
Definition: solgame.cpp:4
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define TDI_SEND_PARTIAL
Definition: tdi.h:136
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define MSG_PARTIAL
Definition: winsock.h:402
#define IOCTL_AFD_SEND
Definition: shared.h:281
struct _AFD_WSABUF * PAFD_WSABUF
HANDLE GlobalHeap
Definition: dllmain.c:19
PAFD_WSABUF BufferArray
Definition: shared.h:101
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
#define INFINITE
Definition: serial.h:102
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by WSPSendTo(), and WSPStartup().

◆ WSPSendDisconnect()

INT WSPAPI WSPSendDisconnect ( IN SOCKET  s,
IN LPWSABUF  lpOutboundDisconnectData,
OUT LPINT  lpErrno 
)

Definition at line 931 of file sndrcv.c.

934 {
936  return 0;
937 }
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by WSPStartup().

◆ WSPSendTo()

int WSPAPI WSPSendTo ( SOCKET  Handle,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesSent,
DWORD  iFlags,
const struct sockaddr SocketAddress,
int  SocketAddressLength,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 719 of file sndrcv.c.

730 {
731  PIO_STATUS_BLOCK IOSB;
732  IO_STATUS_BLOCK DummyIOSB;
733  AFD_SEND_INFO_UDP SendInfo;
735  PVOID APCContext;
736  PVOID APCFunction;
737  HANDLE Event = NULL;
739  PSOCKADDR BindAddress = NULL;
740  INT BindAddressLength;
742  PSOCKET_INFORMATION Socket;
743 
744  /* Get the Socket Structure associate to this Socket */
745  Socket = GetSocketStructure(Handle);
746  if (!Socket)
747  {
748  if (lpErrno)
749  *lpErrno = WSAENOTSOCK;
750  return SOCKET_ERROR;
751  }
752  if (!lpNumberOfBytesSent && !lpOverlapped)
753  {
754  if (lpErrno)
755  *lpErrno = WSAEFAULT;
756  return SOCKET_ERROR;
757  }
758 
759  if (!(Socket->SharedData->ServiceFlags1 & XP1_CONNECTIONLESS))
760  {
761  /* Use WSPSend for connection-oriented sockets */
762  return WSPSend(Handle,
763  lpBuffers,
764  dwBufferCount,
765  lpNumberOfBytesSent,
766  iFlags,
767  lpOverlapped,
768  lpCompletionRoutine,
769  lpThreadId,
770  lpErrno);
771  }
772 
773  /* Bind us First */
774  if (Socket->SharedData->State == SocketOpen)
775  {
776  /* Get the Wildcard Address */
777  BindAddressLength = Socket->HelperData->MaxWSAddressLength;
778  BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength);
779  if (!BindAddress)
780  {
782  return INVALID_SOCKET;
783  }
784 
786  BindAddress,
787  &BindAddressLength);
788  /* Bind it */
789  if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR)
790  return SOCKET_ERROR;
791  }
792 
793  RemoteAddress = HeapAlloc(GlobalHeap, 0, 0x6 + SocketAddressLength);
794  if (!RemoteAddress)
795  {
796  if (BindAddress != NULL)
797  {
798  HeapFree(GlobalHeap, 0, BindAddress);
799  }
801  }
802 
806 
807  if (!NT_SUCCESS(Status))
808  {
810  if (BindAddress != NULL)
811  {
812  HeapFree(GlobalHeap, 0, BindAddress);
813  }
814  return SOCKET_ERROR;
815  }
816 
817  /* Set up Address in TDI Format */
818  RemoteAddress->TAAddressCount = 1;
819  RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
820  RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength);
821 
822  /* Set up Structure */
823  SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
824  SendInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
825  SendInfo.BufferCount = dwBufferCount;
828 
829  /* Verify if we should use APC */
830  if (lpOverlapped == NULL)
831  {
832  /* Not using Overlapped structure, so use normal blocking on event */
833  APCContext = NULL;
834  APCFunction = NULL;
835  Event = SockEvent;
836  IOSB = &DummyIOSB;
837  }
838  else
839  {
840  /* Overlapped request for non overlapped opened socket */
841  if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
842  {
843  TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
844  return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent);
845  }
846  if (lpCompletionRoutine == NULL)
847  {
848  /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
849  APCContext = lpOverlapped;
850  APCFunction = NULL;
851  Event = lpOverlapped->hEvent;
852  }
853  else
854  {
855  /* Using Overlapped Structure and a Completion Routine, so use an APC */
856  APCFunction = &AfdAPC; // should be a private io completion function inside us
857  APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
858  if (!APCContext)
859  {
860  ERR("Not enough memory for APC Context\n");
861  return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent);
862  }
863  ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
864  ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
865  ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
866  SendInfo.AfdFlags |= AFD_SKIP_FIO;
867  }
868 
869  IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
870  SendInfo.AfdFlags |= AFD_OVERLAPPED;
871  }
872 
873  /* Send IOCTL */
875  Event,
876  APCFunction,
877  APCContext,
878  IOSB,
880  &SendInfo,
881  sizeof(SendInfo),
882  NULL,
883  0);
884 
885  /* Wait for completion of not overlapped */
886  if (Status == STATUS_PENDING && lpOverlapped == NULL)
887  {
888  /* BUGBUG, shouldn't wait infinitely for send... */
890  Status = IOSB->Status;
891  }
892 
895  if (BindAddress != NULL)
896  {
897  HeapFree(GlobalHeap, 0, BindAddress);
898  }
899 
900  if (Status == STATUS_PENDING)
901  {
902  TRACE("Leaving (Pending)\n");
903  return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
904  }
905 
907 
908  if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
909  {
910  lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0);
911  HeapFree(GlobalHeap, 0, (PVOID)APCContext);
912  }
913 
914  return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
915 }
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
#define WSAENOTSOCK
Definition: winerror.h:1951
#define SOCKET_ERROR
Definition: winsock.h:333
HANDLE SockEvent
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WSAEFAULT
Definition: winerror.h:1945
#define AFD_IMMEDIATE
Definition: shared.h:220
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3983
TDI_CONNECTION_INFORMATION TdiConnection
Definition: shared.h:112
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3507
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:100
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
VOID NTAPI AfdAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: sndrcv.c:140
int32_t INT
Definition: typedefs.h:56
DWORD CreateFlags
Definition: msafd.h:81
#define FD_WRITE
Definition: winsock.h:406
#define AFD_SKIP_FIO
Definition: shared.h:218
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
ULONG BufferCount
Definition: shared.h:109
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
INT MaxWSAddressLength
Definition: helpers.h:17
smooth NULL
Definition: ftsmooth.c:416
#define IOCTL_AFD_SEND_DATAGRAM
Definition: shared.h:283
PHELPER_DATA HelperData
Definition: msafd.h:103
PAFD_WSABUF BufferArray
Definition: shared.h:108
BOOLEAN NonBlocking
Definition: msafd.h:74
_In_ HANDLE Handle
Definition: extypes.h:390
#define AFD_OVERLAPPED
Definition: shared.h:219
DWORD ServiceFlags1
Definition: msafd.h:82
#define TRACE(s)
Definition: solgame.cpp:4
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define INVALID_SOCKET
Definition: winsock.h:332
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
int WSPAPI WSPSend(SOCKET Handle, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD iFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
Definition: sndrcv.c:568
struct _AFD_WSABUF * PAFD_WSABUF
HANDLE GlobalHeap
Definition: dllmain.c:19
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:846
Status
Definition: gdiplustypes.h:24
u_short sa_family
Definition: winsock.h:217
#define ERR(fmt,...)
Definition: debug.h:109
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
#define XP1_CONNECTIONLESS
Definition: winsock2.h:436
SOCKET_STATE State
Definition: msafd.h:54
INT MaxTDIAddressLength
Definition: helpers.h:19
PVOID HelperContext
Definition: msafd.h:104
#define INFINITE
Definition: serial.h:102
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define HeapFree(x, y, z)
Definition: compat.h:394
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR RemoteAddress
Definition: wsk.h:170

Referenced by WSPStartup().