ReactOS 0.4.15-dev-7928-g68a8619
sockctrl.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/src/sockctrl.c
5 * PURPOSE: Socket Control/State Support
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ws2_32.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS *****************************************************************/
17
18/*
19 * @implemented
20 */
21INT
24 IN CONST struct sockaddr *name,
26{
29 PWSSOCKET Socket;
30 INT ErrorCode, OldErrorCode = ERROR_SUCCESS;
31 INT Status;
33 DPRINT("connect: %lx, %p, %lx\n", s, name, namelen);
34
35 /* Enter prolog */
38 {
39 /* Get the Socket Context */
40 if ((Socket = WsSockGetSocket(s)))
41 {
42 if (!IsBadReadPtr(name, sizeof(struct sockaddr)))
43 {
44 while (TRUE)
45 {
46 /* Make the call */
48 name,
49 namelen,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 &ErrorCode);
55
56 /* Check if error code was due to the host not being found */
57 if ((Status == SOCKET_ERROR) &&
60 {
61 /* Check if we can try again */
62 if (TryAgain)
63 {
64 /* Save the old error code */
65 OldErrorCode = ErrorCode;
66
67 /* Make sure we don't retry 3 times */
69
70 /* Make the RAS Auto-dial attempt */
71 if (WSAttemptAutodialAddr(name, namelen)) continue;
72 }
73 else
74 {
75 /* Restore the error code */
76 ErrorCode = OldErrorCode;
77 }
78 }
79
80 /* Break out of the loop */
81 break;
82 }
83
84 /* Deference the Socket Context */
85 WsSockDereference(Socket);
86
87 /* Return Provider Value */
88 if (Status == ERROR_SUCCESS) return Status;
89
90 /* If everything seemed fine, then the WSP call failed itself */
92 }
93 else
94 {
95 /* Invalid user pointer */
97 }
98 }
99 else
100 {
101 /* No Socket Context Found */
103 }
104 }
105
106 /* If this is Winsock 1.1, normalize the error code */
107 if ((ErrorCode == WSAEALREADY) && (LOBYTE(Process->Version) == 1))
108 {
109 /* WS 1.1 apps expect this */
111 }
112
113 /* Return with an Error */
115 return SOCKET_ERROR;
116}
117
118/*
119 * @implemented
120 */
121INT
122WSAAPI
124 IN INT backlog)
125{
126 PWSSOCKET Socket;
127 INT Status;
129 DPRINT("connect: %lx, %lx\n", s, backlog);
130
131 /* Check for WSAStartup */
133 {
134 /* Get the Socket Context */
135 if ((Socket = WsSockGetSocket(s)))
136 {
137 /* Make the call */
139 backlog,
140 &ErrorCode);
141 /* Deference the Socket Context */
142 WsSockDereference(Socket);
143
144 /* Return Provider Value */
145 if (Status == ERROR_SUCCESS) return Status;
146
147 /* If everything seemed fine, then the WSP call failed itself */
149 }
150 else
151 {
152 /* No Socket Context Found */
154 }
155 }
156
157 /* Return with an Error */
159 return SOCKET_ERROR;
160}
161
162/*
163 * @implemented
164 */
165INT
166WSAAPI
170{
171 PWSSOCKET Socket;
172 INT Status;
174 DPRINT("getpeername: %lx, %p, %lx\n", s, name, namelen);
175
176 /* Check for WSAStartup */
178 {
179 /* Get the Socket Context */
180 if ((Socket = WsSockGetSocket(s)))
181 {
182 /* Make the call */
184 name,
185 namelen,
186 &ErrorCode);
187 /* Deference the Socket Context */
188 WsSockDereference(Socket);
189
190 /* Return Provider Value */
191 if (Status == ERROR_SUCCESS) return Status;
192
193 /* If everything seemed fine, then the WSP call failed itself */
195 }
196 else
197 {
198 /* No Socket Context Found */
200 }
201 }
202
203 /* Return with an Error */
205 return SOCKET_ERROR;
206}
207
208/*
209 * @implemented
210 */
211INT
212WSAAPI
216{
217 PWSSOCKET Socket;
218 INT Status;
220 DPRINT("getsockname: %lx, %p, %lx\n", s, name, namelen);
221
222 /* Check for WSAStartup */
224 {
225 /* Get the Socket Context */
226 if ((Socket = WsSockGetSocket(s)))
227 {
228 if (name && namelen && (*namelen >= sizeof(*name)))
229 {
230 /* Make the call */
232 name,
233 namelen,
234 &ErrorCode);
235
236 /* Deference the Socket Context */
237 WsSockDereference(Socket);
238
239 /* Return Provider Value */
240 if (Status == ERROR_SUCCESS) return Status;
241
242 /* If everything seemed fine, then the WSP call failed itself */
244 }
245 else
246 {
247 /* Deference the Socket Context */
248 WsSockDereference(Socket);
249
250 /* name or namelen not valid */
252 }
253 }
254 else
255 {
256 /* No Socket Context Found */
258 }
259 }
260
261 /* Return with an Error */
263 return SOCKET_ERROR;
264}
265
266/*
267 * @implemented
268 */
269INT
270WSAAPI
272 IN INT level,
273 IN INT optname,
274 OUT CHAR FAR* optval,
275 IN OUT INT FAR* optlen)
276{
279 PWSSOCKET Socket;
281 INT Status;
282 WSAPROTOCOL_INFOW ProtocolInfo;
283 PCHAR OldOptVal = NULL;
284 INT OldOptLen = 0;
285 DPRINT("getsockopt: %lx, %lx, %lx\n", s, level, optname);
286
287 /* Enter prolog */
289 {
290 /* Check if we're getting the open type */
291 if ((level == SOL_SOCKET) && (optname == SO_OPENTYPE))
292 {
293 /* Validate size */
296 {
297 if (!(optlen) || (*optlen < sizeof(DWORD)))
298 {
299 /* Fail */
303 }
304
305 /* Set the open type */
306 *(DWORD*)optval = Thread->OpenType;
307 *optlen = sizeof(DWORD);
308 }
310 {
313 }
314 _SEH2_END;
315
316 return Status;
317 }
318
319 /* Get the Socket Context */
320 if ((Socket = WsSockGetSocket(s)))
321 {
322 /* Check if ANSI data was requested */
323 if ((level == SOL_SOCKET) && (optname == SO_PROTOCOL_INFOA))
324 {
325 /* Validate size and pointers */
328 {
329 if (!(optval) ||
330 !(optlen) ||
331 (*optlen < sizeof(WSAPROTOCOL_INFOA)))
332 {
333 /* Set return size and error code */
334 *optlen = sizeof(WSAPROTOCOL_INFOA);
337 }
338
339 /* It worked. Save the values */
340 OldOptLen = *optlen;
341 OldOptVal = optval;
342
343 /* Hack them so WSP will know how to deal with it */
344 *optlen = sizeof(WSAPROTOCOL_INFOW);
345 optval = (PCHAR)&ProtocolInfo;
346 optname = SO_PROTOCOL_INFOW;
347 }
349 {
351 }
352 _SEH2_END;
353
354 /* Did we encounter invalid parameters? */
355 if (ErrorCode != NO_ERROR)
356 {
357 /* Dereference the socket and fail */
358 WsSockDereference(Socket);
360 return SOCKET_ERROR;
361 }
362 }
363
364 /* Make the call */
366 level,
367 optname,
368 optval,
369 optlen,
370 &ErrorCode);
371
372 /* Deference the Socket Context */
373 WsSockDereference(Socket);
374
375 /* Check provider value */
376 if (Status == ERROR_SUCCESS)
377 {
378 /* Did we use the A->W hack? */
379 if (!OldOptVal) return Status;
380
381 /* We did, so we have to convert the unicode info to ansi */
384 OldOptVal);
385
386 /* Return the length */
388 {
389 *optlen = OldOptLen;
390 }
392 {
394 }
395 _SEH2_END;
396
397 /* Return success if this worked */
398 if (ErrorCode == ERROR_SUCCESS) return Status;
399 }
400
401 /* If everything seemed fine, then the WSP call failed itself */
403 }
404 else
405 {
406 /* No Socket Context Found */
408 }
409 }
410
411 /* Return with an Error */
413 return SOCKET_ERROR;
414}
415
416/*
417 * @implemented
418 */
419INT
420WSAAPI
422 IN INT level,
423 IN INT optname,
424 IN CONST CHAR FAR* optval,
425 IN INT optlen)
426{
429 PWSSOCKET Socket;
431 INT Status;
432 DPRINT("setsockopt: %lx, %lx, %lx\n", s, level, optname);
433
434 /* Enter prolog */
436 {
437 /* Check if we're changing the open type */
438 if (level == SOL_SOCKET && optname == SO_OPENTYPE)
439 {
440 /* Validate size */
441 if (optlen < sizeof(DWORD))
442 {
443 /* Fail */
445 return SOCKET_ERROR;
446 }
447
448 /* Set the open type */
451 {
452 Thread->OpenType = *(DWORD*)optval;
453 }
455 {
458 }
459 _SEH2_END;
460
461 return Status;
462 }
463 if (!optval && optlen > 0)
464 {
466 return SOCKET_ERROR;
467 }
468
469 /* Get the Socket Context */
470 if ((Socket = WsSockGetSocket(s)))
471 {
472 /* Make the call */
474 level,
475 optname,
476 optval,
477 optlen,
478 &ErrorCode);
479
480 /* Deference the Socket Context */
481 WsSockDereference(Socket);
482
483 /* Return Provider Value */
484 if (Status == ERROR_SUCCESS) return Status;
485
486 /* If everything seemed fine, then the WSP call failed itself */
488 }
489 else
490 {
491 /* No Socket Context Found */
493 }
494 }
495
496 /* Return with an Error */
498 return SOCKET_ERROR;
499}
500
501/*
502 * @implemented
503 */
504INT
505WSAAPI
507 IN INT how)
508{
509 PWSSOCKET Socket;
510 INT Status;
512 DPRINT("shutdown: %lx, %lx\n", s, how);
513
514 /* Check for WSAStartup */
516 {
517 /* Get the Socket Context */
518 if ((Socket = WsSockGetSocket(s)))
519 {
520 /* Make the call */
521 Status = Socket->Provider->Service.lpWSPShutdown(s, how, &ErrorCode);
522
523 /* Deference the Socket Context */
524 WsSockDereference(Socket);
525
526 /* Return Provider Value */
527 if (Status == ERROR_SUCCESS) return Status;
528
529 /* If everything seemed fine, then the WSP call failed itself */
531 }
532 else
533 {
534 /* No Socket Context Found */
536 }
537 }
538
539 /* Return with an Error */
541 return SOCKET_ERROR;
542}
543
544/*
545 * @implemented
546 */
547INT
548WSAAPI
550 IN CONST struct sockaddr *name,
551 IN INT namelen,
552 IN LPWSABUF lpCallerData,
553 OUT LPWSABUF lpCalleeData,
554 IN LPQOS lpSQOS,
555 IN LPQOS lpGQOS)
556{
557 PWSSOCKET Socket;
558 INT Status;
560 DPRINT("WSAConnect: %lx, %lx, %lx, %p\n", s, name, namelen, lpCallerData);
561
562 /* Check for WSAStartup */
564 {
565 /* Get the Socket Context */
566 if ((Socket = WsSockGetSocket(s)))
567 {
568 /* Make the call */
570 name,
571 namelen,
572 lpCallerData,
573 lpCalleeData,
574 lpSQOS,
575 lpGQOS,
576 &ErrorCode);
577 /* Deference the Socket Context */
578 WsSockDereference(Socket);
579
580 /* Return Provider Value */
581 if (Status == ERROR_SUCCESS) return Status;
582
583 /* If everything seemed fine, then the WSP call failed itself */
585 }
586 else
587 {
588 /* No Socket Context Found */
590 }
591 }
592
593 /* Return with an Error */
595 return SOCKET_ERROR;
596}
597
598/*
599 * @implemented
600 */
601BOOL
602WSAAPI
605 OUT LPDWORD lpcbTransfer,
606 IN BOOL fWait,
607 OUT LPDWORD lpdwFlags)
608{
609 PWSSOCKET Socket;
610 INT Status;
612 DPRINT("WSAGetOverlappedResult: %lx, %lx\n", s, lpOverlapped);
613
614 /* Check for WSAStartup */
616 {
617 /* Get the Socket Context */
618 if ((Socket = WsSockGetSocket(s)))
619 {
620 /* Make the call */
623 lpcbTransfer,
624 fWait,
625 lpdwFlags,
626 &ErrorCode);
627 /* Deference the Socket Context */
628 WsSockDereference(Socket);
629
630 /* Return Provider Value */
631 if (Status) return Status;
632 }
633 else
634 {
635 /* No Socket Context Found */
637 }
638 }
639
640 /* Return with an Error */
642 return FALSE;
643}
unsigned char BOOLEAN
@ TryAgain
Definition: bl.h:896
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define FAR
Definition: zlib.h:34
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
#define SO_OPENTYPE
Definition: ws2_32.h:40
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
GLint level
Definition: gl.h:1546
GLdouble s
Definition: gl.h:2039
GLint namelen
Definition: glext.h:7232
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define LOBYTE(W)
Definition: jmemdos.c:487
#define PCHAR
Definition: match.c:90
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define CONST
Definition: pedump.c:81
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define DPRINT
Definition: sndvol32.h:71
INT WSAAPI WSAConnect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen, IN LPWSABUF lpCallerData, OUT LPWSABUF lpCalleeData, IN LPQOS lpSQOS, IN LPQOS lpGQOS)
Definition: sockctrl.c:549
INT WSAAPI getpeername(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:167
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
BOOL WSAAPI WSAGetOverlappedResult(IN SOCKET s, IN LPWSAOVERLAPPED lpOverlapped, OUT LPDWORD lpcbTransfer, IN BOOL fWait, OUT LPDWORD lpdwFlags)
Definition: sockctrl.c:603
WSPPROC_TABLE Service
Definition: ws2_32p.h:80
LPWSPSETSOCKOPT lpWSPSetSockOpt
Definition: ws2spi.h:487
LPWSPGETSOCKNAME lpWSPGetSockName
Definition: ws2spi.h:474
LPWSPGETPEERNAME lpWSPGetPeerName
Definition: ws2spi.h:473
LPWSPSHUTDOWN lpWSPShutdown
Definition: ws2spi.h:488
LPWSPGETSOCKOPT lpWSPGetSockOpt
Definition: ws2spi.h:475
LPWSPCONNECT lpWSPConnect
Definition: ws2spi.h:468
LPWSPGETOVERLAPPEDRESULT lpWSPGetOverlappedResult
Definition: ws2spi.h:472
LPWSPLISTEN lpWSPListen
Definition: ws2spi.h:479
PTPROVIDER Provider
Definition: ws2_32p.h:199
Definition: name.c:39
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define WSAEHOSTUNREACH
Definition: winerror.h:1978
#define WSAEALREADY
Definition: winerror.h:1950
#define WSASYSCALLFAILURE
Definition: winerror.h:1994
#define WSAEINVAL
Definition: winerror.h:1946
#define WSAENOTSOCK
Definition: winerror.h:1951
#define WSAENETUNREACH
Definition: winerror.h:1964
#define WSAEFAULT
Definition: winerror.h:1945
struct _WSAPROTOCOL_INFOW WSAPROTOCOL_INFOW
struct _WSAPROTOCOL_INFOA WSAPROTOCOL_INFOA
#define SO_PROTOCOL_INFOW
Definition: winsock2.h:249
#define SO_PROTOCOL_INFOA
Definition: winsock2.h:248
#define WSAAPI
Definition: winsock2.h:605
BOOL WINAPI WSAttemptAutodialAddr(IN CONST SOCKADDR FAR *Name, IN INT NameLength)
Definition: winsock.c:20
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define SOL_SOCKET
Definition: winsock.h:398
FORCEINLINE DWORD WsQuickProlog(VOID)
Definition: ws2_32p.h:892
VOID WSAAPI WsSockDereference(IN PWSSOCKET Socket)
Definition: dsocket.c:205
INT WSAAPI MapUnicodeProtocolInfoToAnsi(IN LPWSAPROTOCOL_INFOW UnicodeInfo, OUT LPWSAPROTOCOL_INFOA AnsiInfo)
Definition: wsautil.c:224
INT WSAAPI WsApiProlog(OUT PWSPROCESS *Process, OUT PWSTHREAD *Thread)
Definition: wsautil.c:91
PWSSOCKET WSAAPI WsSockGetSocket(IN SOCKET Handle)
Definition: dsocket.c:140
char CHAR
Definition: xmlstorage.h:175