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
15 #include <wine/debug.h>
16 WINE_DEFAULT_DEBUG_CHANNEL(msafd
);
22 WSAEVENT hEventObject
,
27 AFD_EVENT_SELECT_INFO EventSelectInfo
;
28 PSOCKET_INFORMATION Socket
= NULL
;
33 Status
= NtCreateEvent( &SockEvent
, EVENT_ALL_ACCESS
,
36 if( !NT_SUCCESS(Status
) ) return -1;
38 /* Get the Socket Structure associate to this Socket*/
39 Socket
= GetSocketStructure(Handle
);
43 *lpErrno
= WSAENOTSOCK
;
47 /* Set Socket to Non-Blocking */
49 SetSocketInformation(Socket
, AFD_INFO_BLOCKING_MODE
, &BlockMode
, NULL
, NULL
);
50 Socket
->SharedData
->NonBlocking
= TRUE
;
52 /* Deactivate Async Select if there is one */
53 if (Socket
->EventObject
) {
54 Socket
->SharedData
->hWnd
= NULL
;
55 Socket
->SharedData
->wMsg
= 0;
56 Socket
->SharedData
->AsyncEvents
= 0;
57 Socket
->SharedData
->SequenceNumber
++; // This will kill Async Select after the next completion
60 /* Set Structure Info */
61 EventSelectInfo
.EventObject
= hEventObject
;
62 EventSelectInfo
.Events
= 0;
64 /* Set Events to wait for */
65 if (lNetworkEvents
& FD_READ
) {
66 EventSelectInfo
.Events
|= AFD_EVENT_RECEIVE
;
69 if (lNetworkEvents
& FD_WRITE
) {
70 EventSelectInfo
.Events
|= AFD_EVENT_SEND
;
73 if (lNetworkEvents
& FD_OOB
) {
74 EventSelectInfo
.Events
|= AFD_EVENT_OOB_RECEIVE
;
77 if (lNetworkEvents
& FD_ACCEPT
) {
78 EventSelectInfo
.Events
|= AFD_EVENT_ACCEPT
;
81 if (lNetworkEvents
& FD_CONNECT
) {
82 EventSelectInfo
.Events
|= AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
;
85 if (lNetworkEvents
& FD_CLOSE
) {
86 EventSelectInfo
.Events
|= AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
;
89 if (lNetworkEvents
& FD_QOS
) {
90 EventSelectInfo
.Events
|= AFD_EVENT_QOS
;
93 if (lNetworkEvents
& FD_GROUP_QOS
) {
94 EventSelectInfo
.Events
|= AFD_EVENT_GROUP_QOS
;
98 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
103 IOCTL_AFD_EVENT_SELECT
,
105 sizeof(EventSelectInfo
),
109 TRACE("AFD: %x\n", Status
);
111 /* Wait for return */
112 if (Status
== STATUS_PENDING
) {
113 WaitForSingleObject(SockEvent
, INFINITE
);
114 Status
= IOSB
.Status
;
119 NtClose( SockEvent
);
121 if (Status
!= STATUS_SUCCESS
)
123 ERR("Got status 0x%08x.\n", Status
);
124 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
127 TRACE("Closed event\n");
130 Socket
->EventObject
= hEventObject
;
131 Socket
->NetworkEvents
= lNetworkEvents
;
141 WSPEnumNetworkEvents(
143 IN WSAEVENT hEventObject
,
144 OUT LPWSANETWORKEVENTS lpNetworkEvents
,
147 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq
;
148 IO_STATUS_BLOCK IOSB
;
149 PSOCKET_INFORMATION Socket
= NULL
;
153 TRACE("Called (lpNetworkEvents %x)\n", lpNetworkEvents
);
155 Status
= NtCreateEvent( &SockEvent
, EVENT_ALL_ACCESS
,
158 if( !NT_SUCCESS(Status
) ) {
159 ERR("Could not make an event %x\n", Status
);
163 /* Get the Socket Structure associate to this Socket*/
164 Socket
= GetSocketStructure(Handle
);
168 *lpErrno
= WSAENOTSOCK
;
172 EnumReq
.Event
= hEventObject
;
175 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
180 IOCTL_AFD_ENUM_NETWORK_EVENTS
,
186 TRACE("AFD: %x\n", Status
);
188 /* Wait for return */
189 if (Status
== STATUS_PENDING
) {
190 WaitForSingleObject(SockEvent
, INFINITE
);
191 Status
= IOSB
.Status
;
196 NtClose( SockEvent
);
198 if (Status
!= STATUS_SUCCESS
)
200 ERR("Status 0x%08x", Status
);
201 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
204 TRACE("Closed event\n");
205 TRACE("About to touch struct at %x (%d)\n", lpNetworkEvents
, sizeof(*lpNetworkEvents
));
207 lpNetworkEvents
->lNetworkEvents
= 0;
209 /* Set Events to wait for */
210 if (EnumReq
.PollEvents
& AFD_EVENT_RECEIVE
) {
211 lpNetworkEvents
->lNetworkEvents
|= FD_READ
;
212 lpNetworkEvents
->iErrorCode
[FD_READ_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_READ_BIT
]);
215 if (EnumReq
.PollEvents
& AFD_EVENT_SEND
) {
216 lpNetworkEvents
->lNetworkEvents
|= FD_WRITE
;
217 lpNetworkEvents
->iErrorCode
[FD_WRITE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_WRITE_BIT
]);
220 if (EnumReq
.PollEvents
& AFD_EVENT_OOB_RECEIVE
) {
221 lpNetworkEvents
->lNetworkEvents
|= FD_OOB
;
222 lpNetworkEvents
->iErrorCode
[FD_OOB_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_OOB_BIT
]);
225 if (EnumReq
.PollEvents
& AFD_EVENT_ACCEPT
) {
226 lpNetworkEvents
->lNetworkEvents
|= FD_ACCEPT
;
227 lpNetworkEvents
->iErrorCode
[FD_ACCEPT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_ACCEPT_BIT
]);
230 if (EnumReq
.PollEvents
&
231 (AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
)) {
232 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
233 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CONNECT_BIT
]);
236 if (EnumReq
.PollEvents
&
237 (AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
)) {
238 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
239 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CLOSE_BIT
]);
242 if (EnumReq
.PollEvents
& AFD_EVENT_QOS
) {
243 lpNetworkEvents
->lNetworkEvents
|= FD_QOS
;
244 lpNetworkEvents
->iErrorCode
[FD_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_QOS_BIT
]);
247 if (EnumReq
.PollEvents
& AFD_EVENT_GROUP_QOS
) {
248 lpNetworkEvents
->lNetworkEvents
|= FD_GROUP_QOS
;
249 lpNetworkEvents
->iErrorCode
[FD_GROUP_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_GROUP_QOS_BIT
]);
254 return MsafdReturnWithErrno(STATUS_SUCCESS
, lpErrno
, 0, NULL
);