2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
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 WSAEVENT hEventObject
,
24 AFD_EVENT_SELECT_INFO EventSelectInfo
;
25 PSOCKET_INFORMATION Socket
= NULL
;
30 Status
= NtCreateEvent( &SockEvent
, EVENT_ALL_ACCESS
,
33 if( !NT_SUCCESS(Status
) ) return -1;
35 /* Get the Socket Structure associate to this Socket*/
36 Socket
= GetSocketStructure(Handle
);
40 *lpErrno
= WSAENOTSOCK
;
44 /* Set Socket to Non-Blocking */
46 SetSocketInformation(Socket
, AFD_INFO_BLOCKING_MODE
, &BlockMode
, NULL
, NULL
);
47 Socket
->SharedData
.NonBlocking
= TRUE
;
49 /* Deactivate Async Select if there is one */
50 if (Socket
->EventObject
) {
51 Socket
->SharedData
.hWnd
= NULL
;
52 Socket
->SharedData
.wMsg
= 0;
53 Socket
->SharedData
.AsyncEvents
= 0;
54 Socket
->SharedData
.SequenceNumber
++; // This will kill Async Select after the next completion
57 /* Set Structure Info */
58 EventSelectInfo
.EventObject
= hEventObject
;
59 EventSelectInfo
.Events
= 0;
61 /* Set Events to wait for */
62 if (lNetworkEvents
& FD_READ
) {
63 EventSelectInfo
.Events
|= AFD_EVENT_RECEIVE
;
66 if (lNetworkEvents
& FD_WRITE
) {
67 EventSelectInfo
.Events
|= AFD_EVENT_SEND
;
70 if (lNetworkEvents
& FD_OOB
) {
71 EventSelectInfo
.Events
|= AFD_EVENT_OOB_RECEIVE
;
74 if (lNetworkEvents
& FD_ACCEPT
) {
75 EventSelectInfo
.Events
|= AFD_EVENT_ACCEPT
;
78 if (lNetworkEvents
& FD_CONNECT
) {
79 EventSelectInfo
.Events
|= AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
;
82 if (lNetworkEvents
& FD_CLOSE
) {
83 EventSelectInfo
.Events
|= AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
;
86 if (lNetworkEvents
& FD_QOS
) {
87 EventSelectInfo
.Events
|= AFD_EVENT_QOS
;
90 if (lNetworkEvents
& FD_GROUP_QOS
) {
91 EventSelectInfo
.Events
|= AFD_EVENT_GROUP_QOS
;
95 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
100 IOCTL_AFD_EVENT_SELECT
,
102 sizeof(EventSelectInfo
),
106 AFD_DbgPrint(MID_TRACE
,("AFD: %x\n", Status
));
108 /* Wait for return */
109 if (Status
== STATUS_PENDING
) {
110 WaitForSingleObject(SockEvent
, INFINITE
);
111 Status
= IOSB
.Status
;
114 AFD_DbgPrint(MID_TRACE
,("Waited\n"));
116 NtClose( SockEvent
);
118 if (Status
!= STATUS_SUCCESS
)
119 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
121 AFD_DbgPrint(MID_TRACE
,("Closed event\n"));
124 Socket
->EventObject
= hEventObject
;
125 Socket
->NetworkEvents
= lNetworkEvents
;
127 AFD_DbgPrint(MID_TRACE
,("Leaving\n"));
135 WSPEnumNetworkEvents(
137 IN WSAEVENT hEventObject
,
138 OUT LPWSANETWORKEVENTS lpNetworkEvents
,
141 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq
;
142 IO_STATUS_BLOCK IOSB
;
143 PSOCKET_INFORMATION Socket
= NULL
;
147 AFD_DbgPrint(MID_TRACE
,("Called (lpNetworkEvents %x)\n", lpNetworkEvents
));
149 Status
= NtCreateEvent( &SockEvent
, EVENT_ALL_ACCESS
,
152 if( !NT_SUCCESS(Status
) ) {
153 AFD_DbgPrint(MID_TRACE
,("Could not make an event %x\n", Status
));
157 /* Get the Socket Structure associate to this Socket*/
158 Socket
= GetSocketStructure(Handle
);
162 *lpErrno
= WSAENOTSOCK
;
166 EnumReq
.Event
= hEventObject
;
169 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
174 IOCTL_AFD_ENUM_NETWORK_EVENTS
,
180 AFD_DbgPrint(MID_TRACE
,("AFD: %x\n", Status
));
182 /* Wait for return */
183 if (Status
== STATUS_PENDING
) {
184 WaitForSingleObject(SockEvent
, INFINITE
);
185 Status
= IOSB
.Status
;
188 AFD_DbgPrint(MID_TRACE
,("Waited\n"));
190 NtClose( SockEvent
);
192 if (Status
!= STATUS_SUCCESS
)
193 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
195 AFD_DbgPrint(MID_TRACE
,("Closed event\n"));
196 AFD_DbgPrint(MID_TRACE
,("About to touch struct at %x (%d)\n",
197 lpNetworkEvents
, sizeof(*lpNetworkEvents
)));
199 lpNetworkEvents
->lNetworkEvents
= 0;
201 AFD_DbgPrint(MID_TRACE
,("Zeroed struct\n"));
203 /* Set Events to wait for */
204 if (EnumReq
.PollEvents
& AFD_EVENT_RECEIVE
) {
205 lpNetworkEvents
->lNetworkEvents
|= FD_READ
;
206 lpNetworkEvents
->iErrorCode
[FD_READ_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_READ_BIT
]);
209 if (EnumReq
.PollEvents
& AFD_EVENT_SEND
) {
210 lpNetworkEvents
->lNetworkEvents
|= FD_WRITE
;
211 lpNetworkEvents
->iErrorCode
[FD_WRITE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_WRITE_BIT
]);
214 if (EnumReq
.PollEvents
& AFD_EVENT_OOB_RECEIVE
) {
215 lpNetworkEvents
->lNetworkEvents
|= FD_OOB
;
216 lpNetworkEvents
->iErrorCode
[FD_OOB_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_OOB_BIT
]);
219 if (EnumReq
.PollEvents
& AFD_EVENT_ACCEPT
) {
220 lpNetworkEvents
->lNetworkEvents
|= FD_ACCEPT
;
221 lpNetworkEvents
->iErrorCode
[FD_ACCEPT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_ACCEPT_BIT
]);
224 if (EnumReq
.PollEvents
&
225 (AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
)) {
226 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
227 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CONNECT_BIT
]);
230 if (EnumReq
.PollEvents
&
231 (AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
)) {
232 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
233 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CLOSE_BIT
]);
236 if (EnumReq
.PollEvents
& AFD_EVENT_QOS
) {
237 lpNetworkEvents
->lNetworkEvents
|= FD_QOS
;
238 lpNetworkEvents
->iErrorCode
[FD_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_QOS_BIT
]);
241 if (EnumReq
.PollEvents
& AFD_EVENT_GROUP_QOS
) {
242 lpNetworkEvents
->lNetworkEvents
|= FD_GROUP_QOS
;
243 lpNetworkEvents
->iErrorCode
[FD_GROUP_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_GROUP_QOS_BIT
]);
246 AFD_DbgPrint(MID_TRACE
,("Leaving\n"));
248 return MsafdReturnWithErrno(STATUS_SUCCESS
, lpErrno
, 0, NULL
);