2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32_new/src/sockctrl.c
5 * PURPOSE: Socket Control/State Support
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
16 /* FUNCTIONS *****************************************************************/
24 IN CONST
struct sockaddr
*name
,
30 INT ErrorCode
, OldErrorCode
= ERROR_SUCCESS
;
32 BOOLEAN TryAgain
= TRUE
;
33 DPRINT("connect: %lx, %p, %lx\n", s
, name
, namelen
);
36 ErrorCode
= WsApiProlog(&Process
, &Thread
);
37 if (ErrorCode
== ERROR_SUCCESS
)
39 /* Get the Socket Context */
40 if ((Socket
= WsSockGetSocket(s
)))
45 Status
= Socket
->Provider
->Service
.lpWSPConnect(s
,
54 /* Check if error code was due to the host not being found */
55 if ((Status
== SOCKET_ERROR
) &&
56 ((ErrorCode
== WSAEHOSTUNREACH
) ||
57 (ErrorCode
== WSAENETUNREACH
)))
59 /* Check if we can try again */
62 /* Save the old error code */
63 OldErrorCode
= ErrorCode
;
65 /* Make sure we don't retry 3 times */
68 /* Make the RAS Auto-dial attempt */
69 if (WSAttemptAutodialAddr(name
, namelen
)) continue;
73 /* Restore the error code */
74 ErrorCode
= OldErrorCode
;
78 /* Break out of the loop */
82 /* Deference the Socket Context */
83 WsSockDereference(Socket
);
85 /* Return Provider Value */
86 if (Status
== ERROR_SUCCESS
) return Status
;
88 /* If everything seemed fine, then the WSP call failed itself */
89 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
93 /* No Socket Context Found */
94 ErrorCode
= WSAENOTSOCK
;
98 /* If this is Winsock 1.1, normalize the error code */
99 if ((ErrorCode
== WSAEALREADY
) && (LOBYTE(Process
->Version
) == 1))
101 /* WS 1.1 apps expect this */
102 ErrorCode
= WSAEINVAL
;
105 /* Return with an Error */
106 SetLastError(ErrorCode
);
121 DPRINT("connect: %lx, %lx\n", s
, backlog
);
123 /* Check for WSAStartup */
124 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
126 /* Get the Socket Context */
127 if ((Socket
= WsSockGetSocket(s
)))
130 Status
= Socket
->Provider
->Service
.lpWSPListen(s
,
133 /* Deference the Socket Context */
134 WsSockDereference(Socket
);
136 /* Return Provider Value */
137 if (Status
== ERROR_SUCCESS
) return Status
;
139 /* If everything seemed fine, then the WSP call failed itself */
140 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
144 /* No Socket Context Found */
145 ErrorCode
= WSAENOTSOCK
;
149 /* Return with an Error */
150 SetLastError(ErrorCode
);
159 getpeername(IN SOCKET s
,
161 IN OUT INT FAR
* namelen
)
166 DPRINT("getpeername: %lx, %p, %lx\n", s
, name
, namelen
);
168 /* Check for WSAStartup */
169 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
171 /* Get the Socket Context */
172 if ((Socket
= WsSockGetSocket(s
)))
175 Status
= Socket
->Provider
->Service
.lpWSPGetPeerName(s
,
179 /* Deference the Socket Context */
180 WsSockDereference(Socket
);
182 /* Return Provider Value */
183 if (Status
== ERROR_SUCCESS
) return Status
;
185 /* If everything seemed fine, then the WSP call failed itself */
186 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
190 /* No Socket Context Found */
191 ErrorCode
= WSAENOTSOCK
;
195 /* Return with an Error */
196 SetLastError(ErrorCode
);
205 getsockname(IN SOCKET s
,
207 IN OUT INT FAR
* namelen
)
212 DPRINT("getsockname: %lx, %p, %lx\n", s
, name
, namelen
);
214 /* Check for WSAStartup */
215 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
217 /* Get the Socket Context */
218 if ((Socket
= WsSockGetSocket(s
)))
220 if (name
&& namelen
&& (*namelen
>= sizeof(*name
)))
223 Status
= Socket
->Provider
->Service
.lpWSPGetSockName(s
,
228 /* Deference the Socket Context */
229 WsSockDereference(Socket
);
231 /* Return Provider Value */
232 if (Status
== ERROR_SUCCESS
) return Status
;
234 /* If everything seemed fine, then the WSP call failed itself */
235 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
239 /* Deference the Socket Context */
240 WsSockDereference(Socket
);
242 /* name or namelen not valid */
243 ErrorCode
= WSAEFAULT
;
248 /* No Socket Context Found */
249 ErrorCode
= WSAENOTSOCK
;
253 /* Return with an Error */
254 SetLastError(ErrorCode
);
263 getsockopt(IN SOCKET s
,
266 OUT CHAR FAR
* optval
,
267 IN OUT INT FAR
* optlen
)
274 WSAPROTOCOL_INFOW ProtocolInfo
;
275 PCHAR OldOptVal
= NULL
;
277 DPRINT("getsockopt: %lx, %lx, %lx\n", s
, level
, optname
);
280 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
282 /* Check if we're getting the open type */
283 if ((level
== SOL_SOCKET
) && (optname
== SO_OPENTYPE
))
286 Status
= ERROR_SUCCESS
;
289 if (!(optlen
) || (*optlen
< sizeof(DWORD
)))
292 Status
= SOCKET_ERROR
;
293 SetLastError(WSAEFAULT
);
297 /* Set the open type */
298 *(DWORD
*)optval
= Thread
->OpenType
;
299 *optlen
= sizeof(DWORD
);
301 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
303 Status
= SOCKET_ERROR
;
304 SetLastError(WSAEFAULT
);
311 /* Get the Socket Context */
312 if ((Socket
= WsSockGetSocket(s
)))
314 /* Check if ANSI data was requested */
315 if ((level
== SOL_SOCKET
) && (optname
== SO_PROTOCOL_INFOA
))
317 /* Validate size and pointers */
318 ErrorCode
= NO_ERROR
;
323 (*optlen
< sizeof(WSAPROTOCOL_INFOA
)))
325 /* Set return size and error code */
326 *optlen
= sizeof(WSAPROTOCOL_INFOA
);
327 ErrorCode
= WSAEFAULT
;
331 /* It worked. Save the values */
335 /* Hack them so WSP will know how to deal with it */
336 *optlen
= sizeof(WSAPROTOCOL_INFOW
);
337 optval
= (PCHAR
)&ProtocolInfo
;
338 optname
= SO_PROTOCOL_INFOW
;
340 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
342 ErrorCode
= WSAEFAULT
;
346 /* Did we encounter invalid parameters? */
347 if (ErrorCode
!= NO_ERROR
)
349 /* Dereference the socket and fail */
350 WsSockDereference(Socket
);
351 SetLastError(ErrorCode
);
357 Status
= Socket
->Provider
->Service
.lpWSPGetSockOpt(s
,
364 /* Deference the Socket Context */
365 WsSockDereference(Socket
);
367 /* Check provider value */
368 if (Status
== ERROR_SUCCESS
)
370 /* Did we use the A->W hack? */
371 if (!OldOptVal
) return Status
;
373 /* We did, so we have to convert the unicode info to ansi */
374 ErrorCode
= MapUnicodeProtocolInfoToAnsi(&ProtocolInfo
,
375 (LPWSAPROTOCOL_INFOA
)
378 /* Return the length */
383 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
385 ErrorCode
= WSAEFAULT
;
389 /* Return success if this worked */
390 if (ErrorCode
== ERROR_SUCCESS
) return Status
;
393 /* If everything seemed fine, then the WSP call failed itself */
394 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
398 /* No Socket Context Found */
399 ErrorCode
= WSAENOTSOCK
;
403 /* Return with an Error */
404 SetLastError(ErrorCode
);
413 setsockopt(IN SOCKET s
,
416 IN CONST CHAR FAR
* optval
,
424 DPRINT("setsockopt: %lx, %lx, %lx\n", s
, level
, optname
);
427 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
429 /* Check if we're changing the open type */
430 if (level
== SOL_SOCKET
&& optname
== SO_OPENTYPE
)
433 if (optlen
< sizeof(DWORD
))
436 SetLastError(WSAEFAULT
);
440 /* Set the open type */
441 Status
= ERROR_SUCCESS
;
444 Thread
->OpenType
= *(DWORD
*)optval
;
446 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
448 Status
= SOCKET_ERROR
;
449 SetLastError(WSAEFAULT
);
455 if (!optval
&& optlen
> 0)
457 SetLastError(WSAEFAULT
);
461 /* Get the Socket Context */
462 if ((Socket
= WsSockGetSocket(s
)))
465 Status
= Socket
->Provider
->Service
.lpWSPSetSockOpt(s
,
472 /* Deference the Socket Context */
473 WsSockDereference(Socket
);
475 /* Return Provider Value */
476 if (Status
== ERROR_SUCCESS
) return Status
;
478 /* If everything seemed fine, then the WSP call failed itself */
479 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
483 /* No Socket Context Found */
484 ErrorCode
= WSAENOTSOCK
;
488 /* Return with an Error */
489 SetLastError(ErrorCode
);
498 shutdown(IN SOCKET s
,
504 DPRINT("shutdown: %lx, %lx\n", s
, how
);
506 /* Check for WSAStartup */
507 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
509 /* Get the Socket Context */
510 if ((Socket
= WsSockGetSocket(s
)))
513 Status
= Socket
->Provider
->Service
.lpWSPShutdown(s
, how
, &ErrorCode
);
515 /* Deference the Socket Context */
516 WsSockDereference(Socket
);
518 /* Return Provider Value */
519 if (Status
== ERROR_SUCCESS
) return Status
;
521 /* If everything seemed fine, then the WSP call failed itself */
522 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
526 /* No Socket Context Found */
527 ErrorCode
= WSAENOTSOCK
;
531 /* Return with an Error */
532 SetLastError(ErrorCode
);
541 WSAConnect(IN SOCKET s
,
542 IN CONST
struct sockaddr
*name
,
544 IN LPWSABUF lpCallerData
,
545 OUT LPWSABUF lpCalleeData
,
552 DPRINT("WSAConnect: %lx, %lx, %lx, %p\n", s
, name
, namelen
, lpCallerData
);
554 /* Check for WSAStartup */
555 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
557 /* Get the Socket Context */
558 if ((Socket
= WsSockGetSocket(s
)))
561 Status
= Socket
->Provider
->Service
.lpWSPConnect(s
,
569 /* Deference the Socket Context */
570 WsSockDereference(Socket
);
572 /* Return Provider Value */
573 if (Status
== ERROR_SUCCESS
) return Status
;
575 /* If everything seemed fine, then the WSP call failed itself */
576 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
580 /* No Socket Context Found */
581 ErrorCode
= WSAENOTSOCK
;
585 /* Return with an Error */
586 SetLastError(ErrorCode
);
595 WSAGetOverlappedResult(IN SOCKET s
,
596 IN LPWSAOVERLAPPED lpOverlapped
,
597 OUT LPDWORD lpcbTransfer
,
599 OUT LPDWORD lpdwFlags
)
604 DPRINT("WSAGetOverlappedResult: %lx, %lx\n", s
, lpOverlapped
);
606 /* Check for WSAStartup */
607 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
609 /* Get the Socket Context */
610 if ((Socket
= WsSockGetSocket(s
)))
613 Status
= Socket
->Provider
->Service
.lpWSPGetOverlappedResult(s
,
619 /* Deference the Socket Context */
620 WsSockDereference(Socket
);
622 /* Return Provider Value */
623 if (Status
) return Status
;
627 /* No Socket Context Found */
628 ErrorCode
= WSAENOTSOCK
;
632 /* Return with an Error */
633 SetLastError(ErrorCode
);