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
)))
221 Status
= Socket
->Provider
->Service
.lpWSPGetSockName(s
,
226 /* Deference the Socket Context */
227 WsSockDereference(Socket
);
229 /* Return Provider Value */
230 if (Status
== ERROR_SUCCESS
) return Status
;
232 /* If everything seemed fine, then the WSP call failed itself */
233 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
237 /* No Socket Context Found */
238 ErrorCode
= WSAENOTSOCK
;
242 /* Return with an Error */
243 SetLastError(ErrorCode
);
252 getsockopt(IN SOCKET s
,
255 OUT CHAR FAR
* optval
,
256 IN OUT INT FAR
* optlen
)
263 WSAPROTOCOL_INFOW ProtocolInfo
;
264 PCHAR OldOptVal
= NULL
;
266 DPRINT("getsockopt: %lx, %lx, %lx\n", s
, level
, optname
);
269 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
271 /* Check if we're getting the open type */
272 if ((level
== SOL_SOCKET
) && (optname
== SO_OPENTYPE
))
275 Status
= ERROR_SUCCESS
;
278 if (!(optlen
) || (*optlen
< sizeof(DWORD
)))
281 Status
= SOCKET_ERROR
;
282 SetLastError(WSAEFAULT
);
286 /* Set the open type */
287 *(DWORD
*)optval
= Thread
->OpenType
;
288 *optlen
= sizeof(DWORD
);
290 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
292 Status
= SOCKET_ERROR
;
293 SetLastError(WSAEFAULT
);
300 /* Get the Socket Context */
301 if ((Socket
= WsSockGetSocket(s
)))
303 /* Check if ANSI data was requested */
304 if ((level
== SOL_SOCKET
) && (optname
== SO_PROTOCOL_INFOA
))
306 /* Validate size and pointers */
307 ErrorCode
= NO_ERROR
;
312 (*optlen
< sizeof(WSAPROTOCOL_INFOA
)))
314 /* Set return size and error code */
315 *optlen
= sizeof(WSAPROTOCOL_INFOA
);
316 ErrorCode
= WSAEFAULT
;
320 /* It worked. Save the values */
324 /* Hack them so WSP will know how to deal with it */
325 *optlen
= sizeof(WSAPROTOCOL_INFOW
);
326 optval
= (PCHAR
)&ProtocolInfo
;
327 optname
= SO_PROTOCOL_INFOW
;
329 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
331 ErrorCode
= WSAEFAULT
;
335 /* Did we encounter invalid parameters? */
336 if (ErrorCode
!= NO_ERROR
)
338 /* Dereference the socket and fail */
339 WsSockDereference(Socket
);
340 SetLastError(ErrorCode
);
346 Status
= Socket
->Provider
->Service
.lpWSPGetSockOpt(s
,
353 /* Deference the Socket Context */
354 WsSockDereference(Socket
);
356 /* Check provider value */
357 if (Status
== ERROR_SUCCESS
)
359 /* Did we use the A->W hack? */
360 if (!OldOptVal
) return Status
;
362 /* We did, so we have to convert the unicode info to ansi */
363 ErrorCode
= MapUnicodeProtocolInfoToAnsi(&ProtocolInfo
,
364 (LPWSAPROTOCOL_INFOA
)
367 /* Return the length */
372 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
374 ErrorCode
= WSAEFAULT
;
378 /* Return success if this worked */
379 if (ErrorCode
== ERROR_SUCCESS
) return Status
;
382 /* If everything seemed fine, then the WSP call failed itself */
383 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
387 /* No Socket Context Found */
388 ErrorCode
= WSAENOTSOCK
;
392 /* Return with an Error */
393 SetLastError(ErrorCode
);
402 setsockopt(IN SOCKET s
,
405 IN CONST CHAR FAR
* optval
,
413 DPRINT("setsockopt: %lx, %lx, %lx\n", s
, level
, optname
);
416 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
418 /* Check if we're changing the open type */
419 if (level
== SOL_SOCKET
&& optname
== SO_OPENTYPE
)
422 if (optlen
< sizeof(DWORD
))
425 SetLastError(WSAEFAULT
);
429 /* Set the open type */
430 Status
= ERROR_SUCCESS
;
433 Thread
->OpenType
= *(DWORD
*)optval
;
435 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
437 Status
= SOCKET_ERROR
;
438 SetLastError(WSAEFAULT
);
444 if (!optval
&& optlen
> 0)
446 SetLastError(WSAEFAULT
);
450 /* Get the Socket Context */
451 if ((Socket
= WsSockGetSocket(s
)))
454 Status
= Socket
->Provider
->Service
.lpWSPSetSockOpt(s
,
461 /* Deference the Socket Context */
462 WsSockDereference(Socket
);
464 /* Return Provider Value */
465 if (Status
== ERROR_SUCCESS
) return Status
;
467 /* If everything seemed fine, then the WSP call failed itself */
468 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
472 /* No Socket Context Found */
473 ErrorCode
= WSAENOTSOCK
;
477 /* Return with an Error */
478 SetLastError(ErrorCode
);
487 shutdown(IN SOCKET s
,
493 DPRINT("shutdown: %lx, %lx\n", s
, how
);
495 /* Check for WSAStartup */
496 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
498 /* Get the Socket Context */
499 if ((Socket
= WsSockGetSocket(s
)))
502 Status
= Socket
->Provider
->Service
.lpWSPShutdown(s
, how
, &ErrorCode
);
504 /* Deference the Socket Context */
505 WsSockDereference(Socket
);
507 /* Return Provider Value */
508 if (Status
== ERROR_SUCCESS
) return Status
;
510 /* If everything seemed fine, then the WSP call failed itself */
511 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
515 /* No Socket Context Found */
516 ErrorCode
= WSAENOTSOCK
;
520 /* Return with an Error */
521 SetLastError(ErrorCode
);
530 WSAConnect(IN SOCKET s
,
531 IN CONST
struct sockaddr
*name
,
533 IN LPWSABUF lpCallerData
,
534 OUT LPWSABUF lpCalleeData
,
541 DPRINT("WSAConnect: %lx, %lx, %lx, %p\n", s
, name
, namelen
, lpCallerData
);
543 /* Check for WSAStartup */
544 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
546 /* Get the Socket Context */
547 if ((Socket
= WsSockGetSocket(s
)))
550 Status
= Socket
->Provider
->Service
.lpWSPConnect(s
,
558 /* Deference the Socket Context */
559 WsSockDereference(Socket
);
561 /* Return Provider Value */
562 if (Status
== ERROR_SUCCESS
) return Status
;
564 /* If everything seemed fine, then the WSP call failed itself */
565 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
569 /* No Socket Context Found */
570 ErrorCode
= WSAENOTSOCK
;
574 /* Return with an Error */
575 SetLastError(ErrorCode
);
584 WSAGetOverlappedResult(IN SOCKET s
,
585 IN LPWSAOVERLAPPED lpOverlapped
,
586 OUT LPDWORD lpcbTransfer
,
588 OUT LPDWORD lpdwFlags
)
593 DPRINT("WSAGetOverlappedResult: %lx, %lx\n", s
, lpOverlapped
);
595 /* Check for WSAStartup */
596 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
598 /* Get the Socket Context */
599 if ((Socket
= WsSockGetSocket(s
)))
602 Status
= Socket
->Provider
->Service
.lpWSPGetOverlappedResult(s
,
608 /* Deference the Socket Context */
609 WsSockDereference(Socket
);
611 /* Return Provider Value */
612 if (Status
) return Status
;
616 /* No Socket Context Found */
617 ErrorCode
= WSAENOTSOCK
;
621 /* Return with an Error */
622 SetLastError(ErrorCode
);