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
8 /* INCLUDES ******************************************************************/
11 /* DATA **********************************************************************/
13 typedef struct _SOCK_EVENT_MAPPING
17 } SOCK_EVENT_MAPPING
, *PSOCK_EVENT_MAPPING
;
19 SOCK_EVENT_MAPPING PollEventMapping
[] =
21 {AFD_EVENT_RECEIVE_BIT
, FD_READ_BIT
},
22 {AFD_EVENT_SEND_BIT
, FD_WRITE_BIT
},
23 {AFD_EVENT_OOB_RECEIVE_BIT
, FD_OOB_BIT
},
24 {AFD_EVENT_ACCEPT_BIT
, FD_ACCEPT_BIT
},
25 {AFD_EVENT_QOS_BIT
, FD_QOS_BIT
},
26 {AFD_EVENT_GROUP_QOS_BIT
, FD_GROUP_QOS_BIT
},
27 {AFD_EVENT_ROUTING_INTERFACE_CHANGE_BIT
, FD_ROUTING_INTERFACE_CHANGE_BIT
},
28 {AFD_EVENT_ADDRESS_LIST_CHANGE_BIT
, FD_ADDRESS_LIST_CHANGE_BIT
}
31 /* FUNCTIONS *****************************************************************/
35 SockEventSelectHelper(IN PSOCKET_INFORMATION Socket
,
36 IN WSAEVENT EventObject
,
39 IO_STATUS_BLOCK IoStatusBlock
;
40 AFD_EVENT_SELECT_INFO PollInfo
;
42 PWINSOCK_TEB_DATA ThreadData
= NtCurrentTeb()->WinSockData
;
44 /* Acquire the lock */
45 EnterCriticalSection(&Socket
->Lock
);
47 /* Set Structure Info */
48 PollInfo
.EventObject
= EventObject
;
51 /* Set receive event */
52 if (Events
& FD_READ
) PollInfo
.Events
|= AFD_EVENT_RECEIVE
;
55 if (Events
& FD_WRITE
) PollInfo
.Events
|= AFD_EVENT_SEND
;
57 /* Set out-of-band (OOB) receive event */
58 if (Events
& FD_OOB
) PollInfo
.Events
|= AFD_EVENT_OOB_RECEIVE
;
60 /* Set accept event */
61 if (Events
& FD_ACCEPT
) PollInfo
.Events
|= AFD_EVENT_ACCEPT
;
63 /* Send Quality-of-Service (QOS) event */
64 if (Events
& FD_QOS
) PollInfo
.Events
|= AFD_EVENT_QOS
;
66 /* Send Group Quality-of-Service (QOS) event */
67 if (Events
& FD_GROUP_QOS
) PollInfo
.Events
|= AFD_EVENT_GROUP_QOS
;
69 /* Send connect event. Note, this also includes connect failures */
70 if (Events
& FD_CONNECT
) PollInfo
.Events
|= AFD_EVENT_CONNECT
|
71 AFD_EVENT_CONNECT_FAIL
;
73 /* Send close event. Note, this includes both aborts and disconnects */
74 if (Events
& FD_CLOSE
) PollInfo
.Events
|= AFD_EVENT_DISCONNECT
|
77 /* Send PnP events related to live network hardware changes */
78 if (Events
& FD_ROUTING_INTERFACE_CHANGE
)
80 PollInfo
.Events
|= AFD_EVENT_ROUTING_INTERFACE_CHANGE
;
82 if (Events
& FD_ADDRESS_LIST_CHANGE
)
84 PollInfo
.Events
|= AFD_EVENT_ADDRESS_LIST_CHANGE
;
88 Status
= NtDeviceIoControlFile(Socket
->WshContext
.Handle
,
89 ThreadData
->EventHandle
,
93 IOCTL_AFD_EVENT_SELECT
,
98 /* Check if we need to wait */
99 if (Status
== STATUS_PENDING
)
101 /* Wait for completion */
102 SockWaitForSingleObject(ThreadData
->EventHandle
,
108 Status
= IoStatusBlock
.Status
;
111 /* Check for error */
112 if (!NT_SUCCESS(Status
))
115 LeaveCriticalSection(&Socket
->Lock
);
116 return NtStatusToSocketError(Status
);
120 Socket
->EventObject
= EventObject
;
121 Socket
->NetworkEvents
= Events
;
123 /* Release lock and return success */
124 LeaveCriticalSection(&Socket
->Lock
);
130 WSPEventSelect(SOCKET Handle
,
131 WSAEVENT hEventObject
,
135 PSOCKET_INFORMATION Socket
;
136 PWINSOCK_TEB_DATA ThreadData
;
141 ErrorCode
= SockEnterApiFast(&ThreadData
);
142 if (ErrorCode
!= NO_ERROR
)
145 *lpErrno
= ErrorCode
;
149 /* Get the socket structure */
150 Socket
= SockFindAndReferenceSocket(Handle
, TRUE
);
154 ErrorCode
= WSAENOTSOCK
;
158 /* Set Socket to Non-Blocking */
160 ErrorCode
= SockSetInformation(Socket
,
161 AFD_INFO_BLOCKING_MODE
,
165 if (ErrorCode
!= NO_ERROR
) goto error
;
167 /* AFD was notified, set it locally as well */
168 Socket
->SharedData
.NonBlocking
= TRUE
;
170 /* Check if there is an async select in progress */
171 if (Socket
->EventObject
)
173 /* Lock the socket */
174 EnterCriticalSection(&Socket
->Lock
);
177 Socket
->SharedData
.hWnd
= NULL
;
178 Socket
->SharedData
.wMsg
= 0;
179 Socket
->SharedData
.AsyncEvents
= 0;
181 /* Unbalance the sequence number so the request will fail */
182 Socket
->SharedData
.SequenceNumber
++;
184 /* Give socket access back */
185 LeaveCriticalSection(&Socket
->Lock
);
188 /* Make sure the flags are valid */
189 if ((lNetworkEvents
& ~FD_ALL_EVENTS
))
191 /* More then the possible combination, fail */
192 ErrorCode
= WSAEINVAL
;
196 /* Call the helper */
197 ErrorCode
= SockEventSelectHelper(Socket
, hEventObject
, lNetworkEvents
);
200 /* Dereference the socket, if we have one here */
201 if (Socket
) SockDereferenceSocket(Socket
);
203 /* Check for error */
204 if (ErrorCode
!= NO_ERROR
)
207 *lpErrno
= ErrorCode
;
217 WSPEnumNetworkEvents(IN SOCKET Handle
,
218 IN WSAEVENT hEventObject
,
219 OUT LPWSANETWORKEVENTS lpNetworkEvents
,
222 AFD_ENUM_NETWORK_EVENTS_INFO EventInfo
;
223 IO_STATUS_BLOCK IoStatusBlock
;
224 PSOCKET_INFORMATION Socket
;
225 PWINSOCK_TEB_DATA ThreadData
;
227 NTSTATUS Status
, EventStatus
;
228 PSOCK_EVENT_MAPPING EventMapping
;
232 ErrorCode
= SockEnterApiFast(&ThreadData
);
233 if (ErrorCode
!= NO_ERROR
)
236 *lpErrno
= ErrorCode
;
240 /* Get the socket structure */
241 Socket
= SockFindAndReferenceSocket(Handle
, TRUE
);
245 ErrorCode
= WSAENOTSOCK
;
249 /* Make sure we got a pointer */
250 if (!lpNetworkEvents
)
253 ErrorCode
= WSAEINVAL
;
257 /* Lock the socket */
258 EnterCriticalSection(&Socket
->Lock
);
261 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
262 ThreadData
->EventHandle
,
266 IOCTL_AFD_ENUM_NETWORK_EVENTS
,
272 /* Check if we need to wait */
273 if (Status
== STATUS_PENDING
)
275 /* Wait for completion */
276 SockWaitForSingleObject(ThreadData
->EventHandle
,
282 Status
= IoStatusBlock
.Status
;
285 /* Check for error */
286 if (!NT_SUCCESS(Status
))
289 ErrorCode
= NtStatusToSocketError(Status
);
293 /* Set Events to wait for */
294 lpNetworkEvents
->lNetworkEvents
= 0;
296 /* Set our Event Mapping structure */
297 EventMapping
= PollEventMapping
;
300 for (i
= 0; i
< (sizeof(PollEventMapping
) / 2 * sizeof(ULONG
)); i
++)
302 /* First check if we have a match for this bit */
303 if (EventInfo
.PollEvents
& (1 << EventMapping
->AfdBit
))
305 /* Match found, write the equivalent bit */
306 lpNetworkEvents
->lNetworkEvents
|= (1 << EventMapping
->WinsockBit
);
308 /* Now get the status */
309 EventStatus
= EventInfo
.EventStatus
[EventMapping
->AfdBit
];
311 /* Check if it failed */
312 if (!NT_SUCCESS(Status
))
314 /* Write the Winsock status code directly */
315 lpNetworkEvents
->iErrorCode
[EventMapping
->WinsockBit
] = NtStatusToSocketError(EventStatus
);
320 lpNetworkEvents
->iErrorCode
[EventMapping
->WinsockBit
] = NO_ERROR
;
323 /* Move to the next mapping array */
327 /* Handle the special cases with two flags. Start with connect */
328 if (EventInfo
.PollEvents
& AFD_EVENT_CONNECT
)
330 /* Set the equivalent bit */
331 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
333 /* Now get the status */
334 EventStatus
= EventInfo
.EventStatus
[AFD_EVENT_CONNECT_BIT
];
336 /* Check if it failed */
337 if (!NT_SUCCESS(Status
))
339 /* Write the Winsock status code directly */
340 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = NtStatusToSocketError(EventStatus
);
345 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = NO_ERROR
;
348 else if (EventInfo
.PollEvents
& AFD_EVENT_CONNECT_FAIL
)
350 /* Do the same thing, but for the failure */
351 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
353 /* Now get the status */
354 EventStatus
= EventInfo
.EventStatus
[AFD_EVENT_CONNECT_FAIL_BIT
];
356 /* Check if it failed */
357 if (!NT_SUCCESS(Status
))
359 /* Write the Winsock status code directly */
360 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = NtStatusToSocketError(EventStatus
);
365 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = NO_ERROR
;
369 /* Now handle Abort/Disconnect */
370 if (EventInfo
.PollEvents
& AFD_EVENT_ABORT
)
372 /* Set the equivalent bit */
373 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
375 /* Now get the status */
376 EventStatus
= EventInfo
.EventStatus
[AFD_EVENT_ABORT_BIT
];
378 /* Check if it failed */
379 if (!NT_SUCCESS(Status
))
381 /* Write the Winsock status code directly */
382 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = NtStatusToSocketError(EventStatus
);
387 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = NO_ERROR
;
390 else if (EventInfo
.PollEvents
& AFD_EVENT_DISCONNECT
)
392 /* Do the same thing, but for the failure */
393 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
395 /* Now get the status */
396 EventStatus
= EventInfo
.EventStatus
[AFD_EVENT_DISCONNECT_BIT
];
398 /* Check if it failed */
399 if (!NT_SUCCESS(Status
))
401 /* Write the Winsock status code directly */
402 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = NtStatusToSocketError(EventStatus
);
407 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = NO_ERROR
;
413 /* Dereference the socket, if we have one here */
414 if (Socket
) SockDereferenceSocket(Socket
);
416 /* Check for error */
417 if (ErrorCode
!= NO_ERROR
)
420 *lpErrno
= ErrorCode
;