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 /* name or namelen not valid */
240 ErrorCode
= WSAEFAULT
;
245 /* No Socket Context Found */
246 ErrorCode
= WSAENOTSOCK
;
250 /* Return with an Error */
251 SetLastError(ErrorCode
);
260 getsockopt(IN SOCKET s
,
263 OUT CHAR FAR
* optval
,
264 IN OUT INT FAR
* optlen
)
271 WSAPROTOCOL_INFOW ProtocolInfo
;
272 PCHAR OldOptVal
= NULL
;
274 DPRINT("getsockopt: %lx, %lx, %lx\n", s
, level
, optname
);
277 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
279 /* Check if we're getting the open type */
280 if ((level
== SOL_SOCKET
) && (optname
== SO_OPENTYPE
))
283 Status
= ERROR_SUCCESS
;
286 if (!(optlen
) || (*optlen
< sizeof(DWORD
)))
289 Status
= SOCKET_ERROR
;
290 SetLastError(WSAEFAULT
);
294 /* Set the open type */
295 *(DWORD
*)optval
= Thread
->OpenType
;
296 *optlen
= sizeof(DWORD
);
298 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
300 Status
= SOCKET_ERROR
;
301 SetLastError(WSAEFAULT
);
308 /* Get the Socket Context */
309 if ((Socket
= WsSockGetSocket(s
)))
311 /* Check if ANSI data was requested */
312 if ((level
== SOL_SOCKET
) && (optname
== SO_PROTOCOL_INFOA
))
314 /* Validate size and pointers */
315 ErrorCode
= NO_ERROR
;
320 (*optlen
< sizeof(WSAPROTOCOL_INFOA
)))
322 /* Set return size and error code */
323 *optlen
= sizeof(WSAPROTOCOL_INFOA
);
324 ErrorCode
= WSAEFAULT
;
328 /* It worked. Save the values */
332 /* Hack them so WSP will know how to deal with it */
333 *optlen
= sizeof(WSAPROTOCOL_INFOW
);
334 optval
= (PCHAR
)&ProtocolInfo
;
335 optname
= SO_PROTOCOL_INFOW
;
337 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
339 ErrorCode
= WSAEFAULT
;
343 /* Did we encounter invalid parameters? */
344 if (ErrorCode
!= NO_ERROR
)
346 /* Dereference the socket and fail */
347 WsSockDereference(Socket
);
348 SetLastError(ErrorCode
);
354 Status
= Socket
->Provider
->Service
.lpWSPGetSockOpt(s
,
361 /* Deference the Socket Context */
362 WsSockDereference(Socket
);
364 /* Check provider value */
365 if (Status
== ERROR_SUCCESS
)
367 /* Did we use the A->W hack? */
368 if (!OldOptVal
) return Status
;
370 /* We did, so we have to convert the unicode info to ansi */
371 ErrorCode
= MapUnicodeProtocolInfoToAnsi(&ProtocolInfo
,
372 (LPWSAPROTOCOL_INFOA
)
375 /* Return the length */
380 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
382 ErrorCode
= WSAEFAULT
;
386 /* Return success if this worked */
387 if (ErrorCode
== ERROR_SUCCESS
) return Status
;
390 /* If everything seemed fine, then the WSP call failed itself */
391 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
395 /* No Socket Context Found */
396 ErrorCode
= WSAENOTSOCK
;
400 /* Return with an Error */
401 SetLastError(ErrorCode
);
410 setsockopt(IN SOCKET s
,
413 IN CONST CHAR FAR
* optval
,
421 DPRINT("setsockopt: %lx, %lx, %lx\n", s
, level
, optname
);
424 if ((ErrorCode
= WsApiProlog(&Process
, &Thread
)) == ERROR_SUCCESS
)
426 /* Check if we're changing the open type */
427 if (level
== SOL_SOCKET
&& optname
== SO_OPENTYPE
)
430 if (optlen
< sizeof(DWORD
))
433 SetLastError(WSAEFAULT
);
437 /* Set the open type */
438 Status
= ERROR_SUCCESS
;
441 Thread
->OpenType
= *(DWORD
*)optval
;
443 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
445 Status
= SOCKET_ERROR
;
446 SetLastError(WSAEFAULT
);
452 if (!optval
&& optlen
> 0)
454 SetLastError(WSAEFAULT
);
458 /* Get the Socket Context */
459 if ((Socket
= WsSockGetSocket(s
)))
462 Status
= Socket
->Provider
->Service
.lpWSPSetSockOpt(s
,
469 /* Deference the Socket Context */
470 WsSockDereference(Socket
);
472 /* Return Provider Value */
473 if (Status
== ERROR_SUCCESS
) return Status
;
475 /* If everything seemed fine, then the WSP call failed itself */
476 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
480 /* No Socket Context Found */
481 ErrorCode
= WSAENOTSOCK
;
485 /* Return with an Error */
486 SetLastError(ErrorCode
);
495 shutdown(IN SOCKET s
,
501 DPRINT("shutdown: %lx, %lx\n", s
, how
);
503 /* Check for WSAStartup */
504 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
506 /* Get the Socket Context */
507 if ((Socket
= WsSockGetSocket(s
)))
510 Status
= Socket
->Provider
->Service
.lpWSPShutdown(s
, how
, &ErrorCode
);
512 /* Deference the Socket Context */
513 WsSockDereference(Socket
);
515 /* Return Provider Value */
516 if (Status
== ERROR_SUCCESS
) return Status
;
518 /* If everything seemed fine, then the WSP call failed itself */
519 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
523 /* No Socket Context Found */
524 ErrorCode
= WSAENOTSOCK
;
528 /* Return with an Error */
529 SetLastError(ErrorCode
);
538 WSAConnect(IN SOCKET s
,
539 IN CONST
struct sockaddr
*name
,
541 IN LPWSABUF lpCallerData
,
542 OUT LPWSABUF lpCalleeData
,
549 DPRINT("WSAConnect: %lx, %lx, %lx, %p\n", s
, name
, namelen
, lpCallerData
);
551 /* Check for WSAStartup */
552 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
554 /* Get the Socket Context */
555 if ((Socket
= WsSockGetSocket(s
)))
558 Status
= Socket
->Provider
->Service
.lpWSPConnect(s
,
566 /* Deference the Socket Context */
567 WsSockDereference(Socket
);
569 /* Return Provider Value */
570 if (Status
== ERROR_SUCCESS
) return Status
;
572 /* If everything seemed fine, then the WSP call failed itself */
573 if (ErrorCode
== NO_ERROR
) ErrorCode
= WSASYSCALLFAILURE
;
577 /* No Socket Context Found */
578 ErrorCode
= WSAENOTSOCK
;
582 /* Return with an Error */
583 SetLastError(ErrorCode
);
592 WSAGetOverlappedResult(IN SOCKET s
,
593 IN LPWSAOVERLAPPED lpOverlapped
,
594 OUT LPDWORD lpcbTransfer
,
596 OUT LPDWORD lpdwFlags
)
601 DPRINT("WSAGetOverlappedResult: %lx, %lx\n", s
, lpOverlapped
);
603 /* Check for WSAStartup */
604 if ((ErrorCode
= WsQuickProlog()) == ERROR_SUCCESS
)
606 /* Get the Socket Context */
607 if ((Socket
= WsSockGetSocket(s
)))
610 Status
= Socket
->Provider
->Service
.lpWSPGetOverlappedResult(s
,
616 /* Deference the Socket Context */
617 WsSockDereference(Socket
);
619 /* Return Provider Value */
620 if (Status
) return Status
;
624 /* No Socket Context Found */
625 ErrorCode
= WSAENOTSOCK
;
629 /* Return with an Error */
630 SetLastError(ErrorCode
);