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
21 WSAEVENT hEventObject
,
26 AFD_EVENT_SELECT_INFO EventSelectInfo
;
27 PSOCKET_INFORMATION Socket
= NULL
;
32 Status
= NtCreateEvent( &SockEvent
, GENERIC_READ
| GENERIC_WRITE
,
35 if( !NT_SUCCESS(Status
) ) return -1;
37 /* Get the Socket Structure associate to this Socket*/
38 Socket
= GetSocketStructure(Handle
);
42 *lpErrno
= WSAENOTSOCK
;
46 /* Set Socket to Non-Blocking */
48 SetSocketInformation(Socket
, AFD_INFO_BLOCKING_MODE
, &BlockMode
, NULL
);
49 Socket
->SharedData
.NonBlocking
= TRUE
;
51 /* Deactivate Async Select if there is one */
52 if (Socket
->EventObject
) {
53 Socket
->SharedData
.hWnd
= NULL
;
54 Socket
->SharedData
.wMsg
= 0;
55 Socket
->SharedData
.AsyncEvents
= 0;
56 Socket
->SharedData
.SequenceNumber
++; // This will kill Async Select after the next completion
59 /* Set Structure Info */
60 EventSelectInfo
.EventObject
= hEventObject
;
61 EventSelectInfo
.Events
= 0;
63 /* Set Events to wait for */
64 if (lNetworkEvents
& FD_READ
) {
65 EventSelectInfo
.Events
|= AFD_EVENT_RECEIVE
;
68 if (lNetworkEvents
& FD_WRITE
) {
69 EventSelectInfo
.Events
|= AFD_EVENT_SEND
;
72 if (lNetworkEvents
& FD_OOB
) {
73 EventSelectInfo
.Events
|= AFD_EVENT_OOB_RECEIVE
;
76 if (lNetworkEvents
& FD_ACCEPT
) {
77 EventSelectInfo
.Events
|= AFD_EVENT_ACCEPT
;
80 if (lNetworkEvents
& FD_CONNECT
) {
81 EventSelectInfo
.Events
|= AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
;
84 if (lNetworkEvents
& FD_CLOSE
) {
85 EventSelectInfo
.Events
|= AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
;
88 if (lNetworkEvents
& FD_QOS
) {
89 EventSelectInfo
.Events
|= AFD_EVENT_QOS
;
92 if (lNetworkEvents
& FD_GROUP_QOS
) {
93 EventSelectInfo
.Events
|= AFD_EVENT_GROUP_QOS
;
97 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
102 IOCTL_AFD_EVENT_SELECT
,
104 sizeof(EventSelectInfo
),
108 AFD_DbgPrint(MID_TRACE
,("AFD: %x\n", Status
));
110 /* Wait for return */
111 if (Status
== STATUS_PENDING
) {
112 WaitForSingleObject(SockEvent
, INFINITE
);
113 Status
= IOSB
.Status
;
116 AFD_DbgPrint(MID_TRACE
,("Waited\n"));
118 NtClose( SockEvent
);
120 if (Status
!= STATUS_SUCCESS
)
121 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
123 AFD_DbgPrint(MID_TRACE
,("Closed event\n"));
126 Socket
->EventObject
= hEventObject
;
127 Socket
->NetworkEvents
= lNetworkEvents
;
129 AFD_DbgPrint(MID_TRACE
,("Leaving\n"));
137 WSPEnumNetworkEvents(
139 IN WSAEVENT hEventObject
,
140 OUT LPWSANETWORKEVENTS lpNetworkEvents
,
143 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq
;
144 IO_STATUS_BLOCK IOSB
;
145 PSOCKET_INFORMATION Socket
= NULL
;
149 AFD_DbgPrint(MID_TRACE
,("Called (lpNetworkEvents %x)\n", lpNetworkEvents
));
151 Status
= NtCreateEvent( &SockEvent
, GENERIC_READ
| GENERIC_WRITE
,
154 if( !NT_SUCCESS(Status
) ) {
155 AFD_DbgPrint(MID_TRACE
,("Could not make an event %x\n", Status
));
159 /* Get the Socket Structure associate to this Socket*/
160 Socket
= GetSocketStructure(Handle
);
164 *lpErrno
= WSAENOTSOCK
;
168 EnumReq
.Event
= hEventObject
;
171 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
176 IOCTL_AFD_ENUM_NETWORK_EVENTS
,
182 AFD_DbgPrint(MID_TRACE
,("AFD: %x\n", Status
));
184 /* Wait for return */
185 if (Status
== STATUS_PENDING
) {
186 WaitForSingleObject(SockEvent
, INFINITE
);
187 Status
= IOSB
.Status
;
190 AFD_DbgPrint(MID_TRACE
,("Waited\n"));
192 NtClose( SockEvent
);
194 if (Status
!= STATUS_SUCCESS
)
195 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
197 AFD_DbgPrint(MID_TRACE
,("Closed event\n"));
198 AFD_DbgPrint(MID_TRACE
,("About to touch struct at %x (%d)\n",
199 lpNetworkEvents
, sizeof(*lpNetworkEvents
)));
201 lpNetworkEvents
->lNetworkEvents
= 0;
203 AFD_DbgPrint(MID_TRACE
,("Zeroed struct\n"));
205 /* Set Events to wait for */
206 if (EnumReq
.PollEvents
& AFD_EVENT_RECEIVE
) {
207 lpNetworkEvents
->lNetworkEvents
|= FD_READ
;
208 lpNetworkEvents
->iErrorCode
[FD_READ_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_READ_BIT
]);
211 if (EnumReq
.PollEvents
& AFD_EVENT_SEND
) {
212 lpNetworkEvents
->lNetworkEvents
|= FD_WRITE
;
213 lpNetworkEvents
->iErrorCode
[FD_WRITE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_WRITE_BIT
]);
216 if (EnumReq
.PollEvents
& AFD_EVENT_OOB_RECEIVE
) {
217 lpNetworkEvents
->lNetworkEvents
|= FD_OOB
;
218 lpNetworkEvents
->iErrorCode
[FD_OOB_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_OOB_BIT
]);
221 if (EnumReq
.PollEvents
& AFD_EVENT_ACCEPT
) {
222 lpNetworkEvents
->lNetworkEvents
|= FD_ACCEPT
;
223 lpNetworkEvents
->iErrorCode
[FD_ACCEPT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_ACCEPT_BIT
]);
226 if (EnumReq
.PollEvents
&
227 (AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
)) {
228 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
229 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CONNECT_BIT
]);
232 if (EnumReq
.PollEvents
&
233 (AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
)) {
234 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
235 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CLOSE_BIT
]);
238 if (EnumReq
.PollEvents
& AFD_EVENT_QOS
) {
239 lpNetworkEvents
->lNetworkEvents
|= FD_QOS
;
240 lpNetworkEvents
->iErrorCode
[FD_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_QOS_BIT
]);
243 if (EnumReq
.PollEvents
& AFD_EVENT_GROUP_QOS
) {
244 lpNetworkEvents
->lNetworkEvents
|= FD_GROUP_QOS
;
245 lpNetworkEvents
->iErrorCode
[FD_GROUP_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_GROUP_QOS_BIT
]);
248 AFD_DbgPrint(MID_TRACE
,("Leaving\n"));
250 return MsafdReturnWithErrno(STATUS_SUCCESS
, lpErrno
, 0, NULL
);