ReactOS 0.4.15-dev-7842-g558ab78
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}
#define HeapFree(x, y, z)
Definition: compat.h:735
HANDLE GlobalHeap
Definition: dllmain.c:19
VOID SockReenableAsyncSelectEvent(IN PSOCKET_INFORMATION Socket, IN ULONG Event)
Definition: dllmain.c:3996
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:727
#define FD_READ
Definition: winsock.h:405
#define FD_WRITE
Definition: winsock.h:406
#define FD_OOB
Definition: winsock.h:407

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{
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;
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}
unsigned char BOOLEAN
HWND hWnd
Definition: settings.c:17
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
HANDLE SockAsyncCompletionPort
Definition: dllmain.c:28
BOOLEAN SockCreateOrReferenceAsyncThread(VOID)
Definition: dllmain.c:3593
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3520
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3962
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:3397
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
Definition: dllmain.c:3688
int WSPAPI WSPEventSelect(IN SOCKET Handle, IN WSAEVENT hEventObject, IN long lNetworkEvents, OUT LPINT lpErrno)
Definition: event.c:17
FORCEINLINE DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, LPDWORD ReturnedBytes)
Definition: msafd.h:546
ULONG Handle
Definition: gdb_input.c:15
NTSTATUS NTAPI NtSetIoCompletion(IN HANDLE IoCompletionPortHandle, IN PVOID CompletionKey, IN PVOID CompletionContext, IN NTSTATUS CompletionStatus, IN ULONG CompletionInformation)
Definition: iocomp.c:569
#define AFD_INFO_BLOCKING_MODE
Definition: shared.h:183
DWORD SequenceNumber
Definition: msafd.h:131
PSOCKET_INFORMATION ParentSocket
Definition: msafd.h:130
PSOCK_SHARED_INFO SharedData
Definition: msafd.h:100
LONG AsyncDisabledEvents
Definition: msafd.h:93
BOOLEAN NonBlocking
Definition: msafd.h:74
LONG AsyncEvents
Definition: msafd.h:92
DWORD SequenceNumber
Definition: msafd.h:90
HANDLE lEvent
Definition: tftpd.cpp:56
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WSAENOTSOCK
Definition: winerror.h:1951
#define INVALID_SOCKET
Definition: winsock.h:332
#define SOCKET_ERROR
Definition: winsock.h:333

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 FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
#define TRACE(s)
Definition: solgame.cpp:4
#define WSAEFAULT
Definition: winerror.h:1945

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 {
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;
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 /* Non-blocking sockets must wait until data is available */
295 if (Status == STATUS_PENDING && Socket->SharedData->NonBlocking)
296 {
297 if (lpErrno) *lpErrno = WSAEWOULDBLOCK;
298 return SOCKET_ERROR;
299 }
300
301 /* Wait for completion of not overlapped */
303 {
304 /* It's up to the protocol to time out recv. We must wait
305 * until the protocol decides it's had enough.
306 */
308 Status = IOSB->Status;
309 }
310
312
313 TRACE("Status %x Information %d\n", Status, IOSB->Information);
314
315 if (Status == STATUS_PENDING)
316 {
317 TRACE("Leaving (Pending)\n");
318 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead);
319 }
320
321 /* Return the Flags */
322 *ReceiveFlags = 0;
323
324 switch (Status)
325 {
327 *ReceiveFlags = MSG_OOB;
328 break;
330 *ReceiveFlags = MSG_PARTIAL | MSG_OOB;
331 break;
333 *ReceiveFlags = MSG_PARTIAL;
334 break;
335 }
336
337 /* Re-enable Async Event */
338 if (*ReceiveFlags & MSG_OOB)
339 {
341 }
342 else
343 {
345 }
346
347 if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
348 {
349 lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags);
350 HeapFree(GlobalHeap, 0, (PVOID)APCContext);
351 }
352
353 return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
354}
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:110
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _AFDAPCCONTEXT * PAFDAPCCONTEXT
HANDLE SockEvent
#define SO_SYNCHRONOUS_NONALERT
Definition: ws2_32.h:41
#define INFINITE
Definition: serial.h:102
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
Status
Definition: gdiplustypes.h:25
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
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)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
@ SynchronizationEvent
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:96
#define STATUS_RECEIVE_EXPEDITED
Definition: ntstatus.h:130
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_RECEIVE_PARTIAL
Definition: ntstatus.h:129
#define STATUS_RECEIVE_PARTIAL_EXPEDITED
Definition: ntstatus.h:131
#define AFD_IMMEDIATE
Definition: shared.h:220
#define AFD_OVERLAPPED
Definition: shared.h:219
#define IOCTL_AFD_RECV
Definition: shared.h:277
#define AFD_SKIP_FIO
Definition: shared.h:218
struct _AFD_WSABUF * PAFD_WSABUF
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID NTAPI AfdAPC(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
Definition: sndrcv.c:140
ULONG BufferCount
Definition: shared.h:86
ULONG TdiFlags
Definition: shared.h:88
ULONG AfdFlags
Definition: shared.h:87
PAFD_WSABUF BufferArray
Definition: shared.h:85
BOOLEAN OobInline
Definition: msafd.h:71
DWORD CreateFlags
Definition: msafd.h:81
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define TDI_RECEIVE_PARTIAL
Definition: tdi.h:121
#define TDI_RECEIVE_EXPEDITED
Definition: tdi.h:123
#define TDI_RECEIVE_PEEK
Definition: tdi.h:124
#define TDI_RECEIVE_NORMAL
Definition: tdi.h:122
#define WSAEWOULDBLOCK
Definition: winerror.h:1948
#define WSAEINVAL
Definition: winerror.h:1946
#define MSG_PEEK
Definition: winsock.h:222
#define MSG_OOB
Definition: winsock.h:221
#define MSG_PARTIAL
Definition: winsock.h:402

Referenced by WSPRecvFrom(), and WSPStartup().

◆ WSPRecvDisconnect()

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

Definition at line 926 of file sndrcv.c.

929{
931 return 0;
932}
#define UNIMPLEMENTED
Definition: debug.h:115

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 358 of file sndrcv.c.

369{
370 PIO_STATUS_BLOCK IOSB;
371 IO_STATUS_BLOCK DummyIOSB;
372 AFD_RECV_INFO_UDP RecvInfo;
374 PVOID APCContext;
375 PVOID APCFunction;
376 HANDLE Event = NULL;
378 PSOCKET_INFORMATION Socket;
379
380 /* Get the Socket Structure associate to this Socket*/
381 Socket = GetSocketStructure(Handle);
382 if (!Socket)
383 {
384 if (lpErrno)
385 *lpErrno = WSAENOTSOCK;
386 return SOCKET_ERROR;
387 }
388 if (!lpNumberOfBytesRead && !lpOverlapped)
389 {
390 if (lpErrno)
391 *lpErrno = WSAEFAULT;
392 return SOCKET_ERROR;
393 }
394 if (Socket->SharedData->OobInline && ReceiveFlags && (*ReceiveFlags & MSG_OOB) != 0)
395 {
396 if (lpErrno)
397 *lpErrno = WSAEINVAL;
398 return SOCKET_ERROR;
399 }
400
402 {
403 /* Call WSPRecv for a non-datagram socket */
404 return WSPRecv(Handle,
405 lpBuffers,
406 dwBufferCount,
407 lpNumberOfBytesRead,
408 ReceiveFlags,
410 lpCompletionRoutine,
411 lpThreadId,
412 lpErrno);
413 }
414
415 /* Bind us First */
416 if (Socket->SharedData->State == SocketOpen)
417 {
419 SocketAddress,
420 SocketAddressLength);
421 /* Bind it */
422 if (WSPBind(Handle, SocketAddress, *SocketAddressLength, lpErrno) == SOCKET_ERROR)
423 return SOCKET_ERROR;
424 }
425
428
429 if( !NT_SUCCESS(Status) )
430 return -1;
431
432 /* Set up the Receive Structure */
433 RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
434 RecvInfo.BufferCount = dwBufferCount;
435 RecvInfo.TdiFlags = 0;
436 RecvInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
437 RecvInfo.AddressLength = SocketAddressLength;
438 RecvInfo.Address = SocketAddress;
439
440 /* Set the TDI Flags */
441 if (*ReceiveFlags == 0)
442 {
443 RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
444 }
445 else
446 {
447 if (*ReceiveFlags & MSG_OOB)
448 {
450 }
451
452 if (*ReceiveFlags & MSG_PEEK)
453 {
454 RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK;
455 }
456
457 if (*ReceiveFlags & MSG_PARTIAL)
458 {
459 RecvInfo.TdiFlags |= TDI_RECEIVE_PARTIAL;
460 }
461 }
462
463 /* Verify if we should use APC */
464
465 if (lpOverlapped == NULL)
466 {
467 /* Not using Overlapped structure, so use normal blocking on event */
468 APCContext = NULL;
469 APCFunction = NULL;
471 IOSB = &DummyIOSB;
472 }
473 else
474 {
475 /* Overlapped request for non overlapped opened socket */
476 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
477 {
478 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
479 return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesRead);
480 }
481 if (lpCompletionRoutine == NULL)
482 {
483 /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
484 APCContext = lpOverlapped;
485 APCFunction = NULL;
486 Event = lpOverlapped->hEvent;
487 }
488 else
489 {
490 /* Using Overlapped Structure and a Completion Routine, so use an APC */
491 APCFunction = &AfdAPC; // should be a private io completion function inside us
492 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
493 if (!APCContext)
494 {
495 ERR("Not enough memory for APC Context\n");
496 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesRead);
497 }
498 ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
499 ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
500 ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
501 RecvInfo.AfdFlags |= AFD_SKIP_FIO;
502 }
503
504 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
505 RecvInfo.AfdFlags |= AFD_OVERLAPPED;
506 }
507
508 IOSB->Status = STATUS_PENDING;
509
510 /* Send IOCTL */
512 Event,
513 APCFunction,
514 APCContext,
515 IOSB,
517 &RecvInfo,
518 sizeof(RecvInfo),
519 NULL,
520 0);
521
522 /* Wait for completion of not overlapped */
524 {
525 WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for receive...
526 Status = IOSB->Status;
527 }
528
530
531 if (Status == STATUS_PENDING)
532 {
533 TRACE("Leaving (Pending)\n");
534 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesRead);
535 }
536
537 /* Return the Flags */
538 *ReceiveFlags = 0;
539
540 switch (Status)
541 {
543 *ReceiveFlags = MSG_OOB;
544 break;
546 *ReceiveFlags = MSG_PARTIAL | MSG_OOB;
547 break;
549 *ReceiveFlags = MSG_PARTIAL;
550 break;
551 }
552
553 /* Re-enable Async Event */
554 if (*ReceiveFlags & MSG_OOB)
555 {
557 }
558 else
559 {
561 }
562
563 if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
564 {
565 lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, *ReceiveFlags);
566 HeapFree(GlobalHeap, 0, (PVOID)APCContext);
567 }
568
569 return MsafdReturnWithErrno ( Status, lpErrno, IOSB->Information, lpNumberOfBytesRead );
570}
INT WSPAPI WSPBind(SOCKET Handle, const struct sockaddr *SocketAddress, int SocketAddressLength, LPINT lpErrno)
Definition: dllmain.c:846
@ SocketOpen
Definition: msafd.h:46
#define IOCTL_AFD_RECV_DATAGRAM
Definition: shared.h:279
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
ULONG AfdFlags
Definition: shared.h:94
PINT AddressLength
Definition: shared.h:97
ULONG BufferCount
Definition: shared.h:93
ULONG TdiFlags
Definition: shared.h:95
PAFD_WSABUF BufferArray
Definition: shared.h:92
PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr
Definition: helpers.h:29
PVOID HelperContext
Definition: msafd.h:104
PHELPER_DATA HelperData
Definition: msafd.h:103
SOCKET_STATE State
Definition: msafd.h:54
DWORD ServiceFlags1
Definition: msafd.h:82
#define XP1_CONNECTIONLESS
Definition: winsock2.h:436

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 575 of file sndrcv.c.

584{
585 PIO_STATUS_BLOCK IOSB;
586 IO_STATUS_BLOCK DummyIOSB;
587 AFD_SEND_INFO SendInfo;
589 PVOID APCContext;
590 PVOID APCFunction;
591 HANDLE Event = NULL;
593 PSOCKET_INFORMATION Socket;
594
595 /* Get the Socket Structure associate to this Socket*/
596 Socket = GetSocketStructure(Handle);
597 if (!Socket)
598 {
599 if (lpErrno)
600 *lpErrno = WSAENOTSOCK;
601 return SOCKET_ERROR;
602 }
603 if (!lpNumberOfBytesSent && !lpOverlapped)
604 {
605 if (lpErrno)
606 *lpErrno = WSAEFAULT;
607 return SOCKET_ERROR;
608 }
609
612
613 if( !NT_SUCCESS(Status) )
614 return -1;
615
616 TRACE("Called\n");
617
618 /* Set up the Send Structure */
619 SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
620 SendInfo.BufferCount = dwBufferCount;
621 SendInfo.TdiFlags = 0;
622 SendInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
623
624 /* Set the TDI Flags */
625 if (iFlags)
626 {
627 if (iFlags & MSG_OOB)
628 {
629 SendInfo.TdiFlags |= TDI_SEND_EXPEDITED;
630 }
631 if (iFlags & MSG_PARTIAL)
632 {
633 SendInfo.TdiFlags |= TDI_SEND_PARTIAL;
634 }
635 }
636
637 /* Verify if we should use APC */
638 if (lpOverlapped == NULL)
639 {
640 /* Not using Overlapped structure, so use normal blocking on event */
641 APCContext = NULL;
642 APCFunction = NULL;
644 IOSB = &DummyIOSB;
645 }
646 else
647 {
648 /* Overlapped request for non overlapped opened socket */
649 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
650 {
651 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
652 return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent);
653 }
654 if (lpCompletionRoutine == NULL)
655 {
656 /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
657 APCContext = lpOverlapped;
658 APCFunction = NULL;
659 Event = lpOverlapped->hEvent;
660 }
661 else
662 {
663 /* Using Overlapped Structure and a Completion Routine, so use an APC */
664 APCFunction = &AfdAPC; // should be a private io completion function inside us
665 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
666 if (!APCContext)
667 {
668 ERR("Not enough memory for APC Context\n");
669 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent);
670 }
671 ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
672 ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
673 ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
674 SendInfo.AfdFlags |= AFD_SKIP_FIO;
675 }
676
677 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
678 SendInfo.AfdFlags |= AFD_OVERLAPPED;
679 }
680
681 IOSB->Status = STATUS_PENDING;
682
683 /* Send IOCTL */
685 Event,
686 APCFunction,
687 APCContext,
688 IOSB,
690 &SendInfo,
691 sizeof(SendInfo),
692 NULL,
693 0);
694
695 /* Wait for completion of not overlapped */
697 {
698 WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for send...
699 Status = IOSB->Status;
700 }
701
703
704 if (Status == STATUS_PENDING)
705 {
706 TRACE("Leaving (Pending)\n");
707 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
708 }
709
710 /* Re-enable Async Event */
712
713 TRACE("Leaving (Success, %d)\n", IOSB->Information);
714
715 if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
716 {
717 lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0);
718 HeapFree(GlobalHeap, 0, (PVOID)APCContext);
719 }
720
721 return MsafdReturnWithErrno( Status, lpErrno, IOSB->Information, lpNumberOfBytesSent );
722}
#define IOCTL_AFD_SEND
Definition: shared.h:281
ULONG BufferCount
Definition: shared.h:102
PAFD_WSABUF BufferArray
Definition: shared.h:101
ULONG TdiFlags
Definition: shared.h:104
ULONG AfdFlags
Definition: shared.h:103
#define TDI_SEND_EXPEDITED
Definition: tdi.h:135
#define TDI_SEND_PARTIAL
Definition: tdi.h:136

Referenced by WSPSendTo(), and WSPStartup().

◆ WSPSendDisconnect()

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

Definition at line 938 of file sndrcv.c.

941{
943 return 0;
944}

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 726 of file sndrcv.c.

737{
738 PIO_STATUS_BLOCK IOSB;
739 IO_STATUS_BLOCK DummyIOSB;
740 AFD_SEND_INFO_UDP SendInfo;
742 PVOID APCContext;
743 PVOID APCFunction;
744 HANDLE Event = NULL;
746 PSOCKADDR BindAddress = NULL;
747 INT BindAddressLength;
749 PSOCKET_INFORMATION Socket;
750
751 /* Get the Socket Structure associate to this Socket */
752 Socket = GetSocketStructure(Handle);
753 if (!Socket)
754 {
755 if (lpErrno)
756 *lpErrno = WSAENOTSOCK;
757 return SOCKET_ERROR;
758 }
759 if (!lpNumberOfBytesSent && !lpOverlapped)
760 {
761 if (lpErrno)
762 *lpErrno = WSAEFAULT;
763 return SOCKET_ERROR;
764 }
765
767 {
768 /* Use WSPSend for connection-oriented sockets */
769 return WSPSend(Handle,
770 lpBuffers,
771 dwBufferCount,
772 lpNumberOfBytesSent,
773 iFlags,
775 lpCompletionRoutine,
776 lpThreadId,
777 lpErrno);
778 }
779
780 /* Bind us First */
781 if (Socket->SharedData->State == SocketOpen)
782 {
783 /* Get the Wildcard Address */
784 BindAddressLength = Socket->HelperData->MaxWSAddressLength;
785 BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength);
786 if (!BindAddress)
787 {
789 return INVALID_SOCKET;
790 }
791
793 BindAddress,
794 &BindAddressLength);
795 /* Bind it */
796 if (WSPBind(Handle, BindAddress, BindAddressLength, lpErrno) == SOCKET_ERROR)
797 return SOCKET_ERROR;
798 }
799
800 RemoteAddress = HeapAlloc(GlobalHeap, 0, 0x6 + SocketAddressLength);
801 if (!RemoteAddress)
802 {
803 if (BindAddress != NULL)
804 {
805 HeapFree(GlobalHeap, 0, BindAddress);
806 }
808 }
809
813
814 if (!NT_SUCCESS(Status))
815 {
817 if (BindAddress != NULL)
818 {
819 HeapFree(GlobalHeap, 0, BindAddress);
820 }
821 return SOCKET_ERROR;
822 }
823
824 /* Set up Address in TDI Format */
825 RemoteAddress->TAAddressCount = 1;
826 RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
827 RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength);
828
829 /* Set up Structure */
830 SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
831 SendInfo.AfdFlags = Socket->SharedData->NonBlocking ? AFD_IMMEDIATE : 0;
832 SendInfo.BufferCount = dwBufferCount;
835
836 /* Verify if we should use APC */
837 if (lpOverlapped == NULL)
838 {
839 /* Not using Overlapped structure, so use normal blocking on event */
840 APCContext = NULL;
841 APCFunction = NULL;
843 IOSB = &DummyIOSB;
844 }
845 else
846 {
847 /* Overlapped request for non overlapped opened socket */
848 if ((Socket->SharedData->CreateFlags & SO_SYNCHRONOUS_NONALERT) != 0)
849 {
850 TRACE("Opened without flag WSA_FLAG_OVERLAPPED. Do nothing.\n");
851 return MsafdReturnWithErrno(0, lpErrno, 0, lpNumberOfBytesSent);
852 }
853 if (lpCompletionRoutine == NULL)
854 {
855 /* Using Overlapped Structure, but no Completion Routine, so no need for APC */
856 APCContext = lpOverlapped;
857 APCFunction = NULL;
858 Event = lpOverlapped->hEvent;
859 }
860 else
861 {
862 /* Using Overlapped Structure and a Completion Routine, so use an APC */
863 APCFunction = &AfdAPC; // should be a private io completion function inside us
864 APCContext = HeapAlloc(GlobalHeap, 0, sizeof(AFDAPCCONTEXT));
865 if (!APCContext)
866 {
867 ERR("Not enough memory for APC Context\n");
868 return MsafdReturnWithErrno(STATUS_INSUFFICIENT_RESOURCES, lpErrno, 0, lpNumberOfBytesSent);
869 }
870 ((PAFDAPCCONTEXT)APCContext)->lpCompletionRoutine = lpCompletionRoutine;
871 ((PAFDAPCCONTEXT)APCContext)->lpOverlapped = lpOverlapped;
872 ((PAFDAPCCONTEXT)APCContext)->lpSocket = Socket;
873 SendInfo.AfdFlags |= AFD_SKIP_FIO;
874 }
875
876 IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
877 SendInfo.AfdFlags |= AFD_OVERLAPPED;
878 }
879
880 /* Send IOCTL */
882 Event,
883 APCFunction,
884 APCContext,
885 IOSB,
887 &SendInfo,
888 sizeof(SendInfo),
889 NULL,
890 0);
891
892 /* Wait for completion of not overlapped */
894 {
895 /* BUGBUG, shouldn't wait infinitely for send... */
897 Status = IOSB->Status;
898 }
899
902 if (BindAddress != NULL)
903 {
904 HeapFree(GlobalHeap, 0, BindAddress);
905 }
906
907 if (Status == STATUS_PENDING)
908 {
909 TRACE("Leaving (Pending)\n");
910 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
911 }
912
914
915 if (Status == STATUS_SUCCESS && lpOverlapped && lpCompletionRoutine)
916 {
917 lpCompletionRoutine(Status, IOSB->Information, lpOverlapped, 0);
918 HeapFree(GlobalHeap, 0, (PVOID)APCContext);
919 }
920
921 return MsafdReturnWithErrno(Status, lpErrno, IOSB->Information, lpNumberOfBytesSent);
922}
#define IOCTL_AFD_SEND_DATAGRAM
Definition: shared.h:283
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:575
ULONG BufferCount
Definition: shared.h:109
TDI_CONNECTION_INFORMATION TdiConnection
Definition: shared.h:112
PAFD_WSABUF BufferArray
Definition: shared.h:108
INT MaxTDIAddressLength
Definition: helpers.h:19
INT MaxWSAddressLength
Definition: helpers.h:17
u_short sa_family
Definition: winsock.h:217
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR RemoteAddress
Definition: wsk.h:172

Referenced by WSPStartup().