2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
4 * FILE: dll/win32/msafd/misc/event.c
5 * PURPOSE: Event handling
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Alex Ionescu (alex@relsoft.net)
9 * CSH 15/06/2001 - Created
10 * Alex 16/07/2004 - Complete Rewrite
19 IN WSAEVENT hEventObject
,
20 IN
long lNetworkEvents
,
24 AFD_EVENT_SELECT_INFO EventSelectInfo
;
25 PSOCKET_INFORMATION Socket
= NULL
;
30 TRACE("WSPEventSelect (%lx) %lx %lx\n", Handle
, hEventObject
, lNetworkEvents
);
32 /* Get the Socket Structure associate to this Socket*/
33 Socket
= GetSocketStructure(Handle
);
36 if (lpErrno
) *lpErrno
= WSAENOTSOCK
;
40 Status
= NtCreateEvent(&SockEvent
, EVENT_ALL_ACCESS
,
43 if (!NT_SUCCESS(Status
)) return SOCKET_ERROR
;
45 /* Set Socket to Non-Blocking */
47 SetSocketInformation(Socket
, AFD_INFO_BLOCKING_MODE
, &BlockMode
, NULL
, NULL
, NULL
, NULL
);
48 Socket
->SharedData
->NonBlocking
= TRUE
;
50 /* Deactivate Async Select if there is one */
51 if (Socket
->EventObject
) {
52 Socket
->SharedData
->hWnd
= NULL
;
53 Socket
->SharedData
->wMsg
= 0;
54 Socket
->SharedData
->AsyncEvents
= 0;
55 Socket
->SharedData
->SequenceNumber
++; // This will kill Async Select after the next completion
58 /* Set Structure Info */
59 EventSelectInfo
.EventObject
= hEventObject
;
60 EventSelectInfo
.Events
= 0;
62 /* Set Events to wait for */
63 if (lNetworkEvents
& FD_READ
) {
64 EventSelectInfo
.Events
|= AFD_EVENT_RECEIVE
;
67 if (lNetworkEvents
& FD_WRITE
) {
68 EventSelectInfo
.Events
|= AFD_EVENT_SEND
;
71 if (lNetworkEvents
& FD_OOB
) {
72 EventSelectInfo
.Events
|= AFD_EVENT_OOB_RECEIVE
;
75 if (lNetworkEvents
& FD_ACCEPT
) {
76 EventSelectInfo
.Events
|= AFD_EVENT_ACCEPT
;
79 if (lNetworkEvents
& FD_CONNECT
) {
80 EventSelectInfo
.Events
|= AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
;
83 if (lNetworkEvents
& FD_CLOSE
) {
84 EventSelectInfo
.Events
|= AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
;
87 if (lNetworkEvents
& FD_QOS
) {
88 EventSelectInfo
.Events
|= AFD_EVENT_QOS
;
91 if (lNetworkEvents
& FD_GROUP_QOS
) {
92 EventSelectInfo
.Events
|= AFD_EVENT_GROUP_QOS
;
96 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
101 IOCTL_AFD_EVENT_SELECT
,
103 sizeof(EventSelectInfo
),
107 /* Wait for return */
108 if (Status
== STATUS_PENDING
) {
109 WaitForSingleObject(SockEvent
, INFINITE
);
110 Status
= IOSB
.Status
;
115 if (Status
!= STATUS_SUCCESS
)
117 ERR("Got status 0x%08x.\n", Status
);
118 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
122 Socket
->EventObject
= hEventObject
;
123 Socket
->NetworkEvents
= lNetworkEvents
;
133 WSPEnumNetworkEvents(
135 IN WSAEVENT hEventObject
,
136 OUT LPWSANETWORKEVENTS lpNetworkEvents
,
139 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq
;
140 IO_STATUS_BLOCK IOSB
;
141 PSOCKET_INFORMATION Socket
= NULL
;
145 TRACE("Called (lpNetworkEvents %x)\n", lpNetworkEvents
);
147 /* Get the Socket Structure associate to this Socket*/
148 Socket
= GetSocketStructure(Handle
);
151 if (lpErrno
) *lpErrno
= WSAENOTSOCK
;
154 if (!lpNetworkEvents
)
156 if (lpErrno
) *lpErrno
= WSAEFAULT
;
160 Status
= NtCreateEvent(&SockEvent
, EVENT_ALL_ACCESS
,
163 if( !NT_SUCCESS(Status
) ) {
164 ERR("Could not make an event %x\n", Status
);
168 EnumReq
.Event
= hEventObject
;
171 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
176 IOCTL_AFD_ENUM_NETWORK_EVENTS
,
182 /* Wait for return */
183 if (Status
== STATUS_PENDING
) {
184 WaitForSingleObject(SockEvent
, INFINITE
);
185 Status
= IOSB
.Status
;
190 if (Status
!= STATUS_SUCCESS
)
192 ERR("Status 0x%08x", Status
);
193 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
196 lpNetworkEvents
->lNetworkEvents
= 0;
198 /* Set Events to wait for */
199 if (EnumReq
.PollEvents
& AFD_EVENT_RECEIVE
) {
200 lpNetworkEvents
->lNetworkEvents
|= FD_READ
;
201 lpNetworkEvents
->iErrorCode
[FD_READ_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_READ_BIT
]);
204 if (EnumReq
.PollEvents
& AFD_EVENT_SEND
) {
205 lpNetworkEvents
->lNetworkEvents
|= FD_WRITE
;
206 lpNetworkEvents
->iErrorCode
[FD_WRITE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_WRITE_BIT
]);
209 if (EnumReq
.PollEvents
& AFD_EVENT_OOB_RECEIVE
) {
210 lpNetworkEvents
->lNetworkEvents
|= FD_OOB
;
211 lpNetworkEvents
->iErrorCode
[FD_OOB_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_OOB_BIT
]);
214 if (EnumReq
.PollEvents
& AFD_EVENT_ACCEPT
) {
215 lpNetworkEvents
->lNetworkEvents
|= FD_ACCEPT
;
216 lpNetworkEvents
->iErrorCode
[FD_ACCEPT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_ACCEPT_BIT
]);
219 if (EnumReq
.PollEvents
&
220 (AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
)) {
221 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
222 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CONNECT_BIT
]);
225 if (EnumReq
.PollEvents
&
226 (AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
)) {
227 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
228 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CLOSE_BIT
]);
231 if (EnumReq
.PollEvents
& AFD_EVENT_QOS
) {
232 lpNetworkEvents
->lNetworkEvents
|= FD_QOS
;
233 lpNetworkEvents
->iErrorCode
[FD_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_QOS_BIT
]);
236 if (EnumReq
.PollEvents
& AFD_EVENT_GROUP_QOS
) {
237 lpNetworkEvents
->lNetworkEvents
|= FD_GROUP_QOS
;
238 lpNetworkEvents
->iErrorCode
[FD_GROUP_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_GROUP_QOS_BIT
]);
243 return MsafdReturnWithErrno(STATUS_SUCCESS
, lpErrno
, 0, NULL
);