- Build fixes
[reactos.git] / dll / win32 / mswsock / msafd / listen.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winsock 2 SPI
4 * FILE: lib/mswsock/lib/init.c
5 * PURPOSE: DLL Initialization
6 */
7
8 /* INCLUDES ******************************************************************/
9 #include "msafd.h"
10
11 /* DATA **********************************************************************/
12
13 /* FUNCTIONS *****************************************************************/
14
15 INT
16 WSPAPI
17 WSPListen(SOCKET Handle,
18 INT Backlog,
19 LPINT lpErrno)
20 {
21 IO_STATUS_BLOCK IoStatusBlock;
22 AFD_LISTEN_DATA ListenData;
23 PSOCKET_INFORMATION Socket;
24 PWINSOCK_TEB_DATA ThreadData;
25 INT ErrorCode;
26 NTSTATUS Status;
27
28 /* Enter prolog */
29 ErrorCode = SockEnterApiFast(&ThreadData);
30 if (ErrorCode != NO_ERROR)
31 {
32 /* Fail */
33 *lpErrno = ErrorCode;
34 return SOCKET_ERROR;
35 }
36
37 /* Get the socket structure */
38 Socket = SockFindAndReferenceSocket(Handle, TRUE);
39 if (!Socket)
40 {
41 /* Fail */
42 ErrorCode = WSAENOTSOCK;
43 goto error;
44 }
45
46 /* Lock the socket */
47 EnterCriticalSection(&Socket->Lock);
48
49 /* If the socket is connection-less, fail */
50 if (MSAFD_IS_DGRAM_SOCK(Socket));
51 {
52 /* Fail */
53 ErrorCode = WSAEOPNOTSUPP;
54 goto error;
55 }
56
57 /* If the socket is already listening, do nothing */
58 if (Socket->SharedData.Listening)
59 {
60 /* Return happily */
61 ErrorCode = NO_ERROR;
62 goto error;
63 }
64 else if (Socket->SharedData.State != SocketConnected)
65 {
66 /* If we're not connected, fail */
67 ErrorCode = WSAEINVAL;
68 goto error;
69 }
70
71 /* Set Up Listen Structure */
72 ListenData.UseSAN = SockSanEnabled;
73 ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance;
74 ListenData.Backlog = Backlog;
75
76 /* Send IOCTL */
77 Status = NtDeviceIoControlFile(Socket->WshContext.Handle,
78 ThreadData->EventHandle,
79 NULL,
80 NULL,
81 &IoStatusBlock,
82 IOCTL_AFD_START_LISTEN,
83 &ListenData,
84 sizeof(ListenData),
85 NULL,
86 0);
87 /* Check if we need to wait */
88 if (Status == STATUS_PENDING)
89 {
90 /* Wait for completion outside the lock */
91 LeaveCriticalSection(&Socket->Lock);
92 SockWaitForSingleObject(ThreadData->EventHandle,
93 Handle,
94 NO_BLOCKING_HOOK,
95 NO_TIMEOUT);
96 EnterCriticalSection(&Socket->Lock);
97
98 /* Get new status */
99 Status = IoStatusBlock.Status;
100 }
101
102 /* Check for error */
103 if (!NT_SUCCESS(Status))
104 {
105 /* Fail */
106 ErrorCode = NtStatusToSocketError(Status);
107 goto error;
108 }
109
110 /* Notify helper DLL */
111 ErrorCode = SockNotifyHelperDll(Socket, WSH_NOTIFY_LISTEN);
112 if (ErrorCode != NO_ERROR) goto error;
113
114 /* Set to Listening */
115 Socket->SharedData.Listening = TRUE;
116
117 /* Update context with AFD */
118 ErrorCode = SockSetHandleContext(Socket);
119 if (ErrorCode != NO_ERROR) goto error;
120
121 error:
122 /* Check if we have a socket here */
123 if (Socket)
124 {
125 /* Release the lock and dereference */
126 LeaveCriticalSection(&Socket->Lock);
127 SockDereferenceSocket(Socket);
128 }
129
130 /* Check for error */
131 if (ErrorCode != NO_ERROR)
132 {
133 /* Fail */
134 *lpErrno = ErrorCode;
135 return SOCKET_ERROR;
136 }
137
138 /* Return success */
139 return NO_ERROR;
140 }
141