ReactOS 0.4.15-dev-5893-g1bb4167
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:3992
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:3589
PSOCKET_INFORMATION GetSocketStructure(SOCKET Handle)
Definition: dllmain.c:3516
VOID SockProcessQueuedAsyncSelect(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock)
Definition: dllmain.c:3958
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:3393
BOOLEAN SockGetAsyncSelectHelperAfdHandle(VOID)
Definition: dllmain.c:3684
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 /* Wait for completion of not overlapped */
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
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}
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 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 919 of file sndrcv.c.

922{
924 return 0;
925}
#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 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
395 {
396 /* Call WSPRecv for a non-datagram socket */
397 return WSPRecv(Handle,
398 lpBuffers,
399 dwBufferCount,
400 lpNumberOfBytesRead,
401 ReceiveFlags,
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 {
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;
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 */
517 {
518 WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for receive...
519 Status = IOSB->Status;
520 }
521
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}
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 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;
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 */
690 {
691 WaitForSingleObject(SockEvent, INFINITE); // BUGBUG, shouldn wait infinitely for send...
692 Status = IOSB->Status;
693 }
694
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 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 931 of file sndrcv.c.

934{
936 return 0;
937}

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
760 {
761 /* Use WSPSend for connection-oriented sockets */
762 return WSPSend(Handle,
763 lpBuffers,
764 dwBufferCount,
765 lpNumberOfBytesSent,
766 iFlags,
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;
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 */
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}
#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:568
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().