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 IN WSAEVENT hEventObject
,
23 IN
long lNetworkEvents
,
27 AFD_EVENT_SELECT_INFO EventSelectInfo
;
28 PSOCKET_INFORMATION Socket
= NULL
;
33 TRACE("WSPEventSelect (%lx) %lx %lx\n", Handle
, hEventObject
, lNetworkEvents
);
35 /* Get the Socket Structure associate to this Socket*/
36 Socket
= GetSocketStructure(Handle
);
39 if (lpErrno
) *lpErrno
= WSAENOTSOCK
;
43 Status
= NtCreateEvent(&SockEvent
, EVENT_ALL_ACCESS
,
46 if (!NT_SUCCESS(Status
)) return SOCKET_ERROR
;
48 /* Set Socket to Non-Blocking */
50 SetSocketInformation(Socket
, AFD_INFO_BLOCKING_MODE
, &BlockMode
, NULL
, NULL
, NULL
, NULL
);
51 Socket
->SharedData
->NonBlocking
= TRUE
;
53 /* Deactivate Async Select if there is one */
54 if (Socket
->EventObject
) {
55 Socket
->SharedData
->hWnd
= NULL
;
56 Socket
->SharedData
->wMsg
= 0;
57 Socket
->SharedData
->AsyncEvents
= 0;
58 Socket
->SharedData
->SequenceNumber
++; // This will kill Async Select after the next completion
61 /* Set Structure Info */
62 EventSelectInfo
.EventObject
= hEventObject
;
63 EventSelectInfo
.Events
= 0;
65 /* Set Events to wait for */
66 if (lNetworkEvents
& FD_READ
) {
67 EventSelectInfo
.Events
|= AFD_EVENT_RECEIVE
;
70 if (lNetworkEvents
& FD_WRITE
) {
71 EventSelectInfo
.Events
|= AFD_EVENT_SEND
;
74 if (lNetworkEvents
& FD_OOB
) {
75 EventSelectInfo
.Events
|= AFD_EVENT_OOB_RECEIVE
;
78 if (lNetworkEvents
& FD_ACCEPT
) {
79 EventSelectInfo
.Events
|= AFD_EVENT_ACCEPT
;
82 if (lNetworkEvents
& FD_CONNECT
) {
83 EventSelectInfo
.Events
|= AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
;
86 if (lNetworkEvents
& FD_CLOSE
) {
87 EventSelectInfo
.Events
|= AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
;
90 if (lNetworkEvents
& FD_QOS
) {
91 EventSelectInfo
.Events
|= AFD_EVENT_QOS
;
94 if (lNetworkEvents
& FD_GROUP_QOS
) {
95 EventSelectInfo
.Events
|= AFD_EVENT_GROUP_QOS
;
99 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
104 IOCTL_AFD_EVENT_SELECT
,
106 sizeof(EventSelectInfo
),
110 /* Wait for return */
111 if (Status
== STATUS_PENDING
) {
112 WaitForSingleObject(SockEvent
, INFINITE
);
113 Status
= IOSB
.Status
;
118 if (Status
!= STATUS_SUCCESS
)
120 ERR("Got status 0x%08x.\n", Status
);
121 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
125 Socket
->EventObject
= hEventObject
;
126 Socket
->NetworkEvents
= lNetworkEvents
;
136 WSPEnumNetworkEvents(
138 IN WSAEVENT hEventObject
,
139 OUT LPWSANETWORKEVENTS lpNetworkEvents
,
142 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq
;
143 IO_STATUS_BLOCK IOSB
;
144 PSOCKET_INFORMATION Socket
= NULL
;
148 TRACE("Called (lpNetworkEvents %x)\n", lpNetworkEvents
);
150 /* Get the Socket Structure associate to this Socket*/
151 Socket
= GetSocketStructure(Handle
);
154 if (lpErrno
) *lpErrno
= WSAENOTSOCK
;
157 if (!lpNetworkEvents
)
159 if (lpErrno
) *lpErrno
= WSAEFAULT
;
163 Status
= NtCreateEvent(&SockEvent
, EVENT_ALL_ACCESS
,
166 if( !NT_SUCCESS(Status
) ) {
167 ERR("Could not make an event %x\n", Status
);
171 EnumReq
.Event
= hEventObject
;
174 Status
= NtDeviceIoControlFile((HANDLE
)Handle
,
179 IOCTL_AFD_ENUM_NETWORK_EVENTS
,
185 /* Wait for return */
186 if (Status
== STATUS_PENDING
) {
187 WaitForSingleObject(SockEvent
, INFINITE
);
188 Status
= IOSB
.Status
;
193 if (Status
!= STATUS_SUCCESS
)
195 ERR("Status 0x%08x", Status
);
196 return MsafdReturnWithErrno(Status
, lpErrno
, 0, NULL
);
199 lpNetworkEvents
->lNetworkEvents
= 0;
201 /* Set Events to wait for */
202 if (EnumReq
.PollEvents
& AFD_EVENT_RECEIVE
) {
203 lpNetworkEvents
->lNetworkEvents
|= FD_READ
;
204 lpNetworkEvents
->iErrorCode
[FD_READ_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_READ_BIT
]);
207 if (EnumReq
.PollEvents
& AFD_EVENT_SEND
) {
208 lpNetworkEvents
->lNetworkEvents
|= FD_WRITE
;
209 lpNetworkEvents
->iErrorCode
[FD_WRITE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_WRITE_BIT
]);
212 if (EnumReq
.PollEvents
& AFD_EVENT_OOB_RECEIVE
) {
213 lpNetworkEvents
->lNetworkEvents
|= FD_OOB
;
214 lpNetworkEvents
->iErrorCode
[FD_OOB_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_OOB_BIT
]);
217 if (EnumReq
.PollEvents
& AFD_EVENT_ACCEPT
) {
218 lpNetworkEvents
->lNetworkEvents
|= FD_ACCEPT
;
219 lpNetworkEvents
->iErrorCode
[FD_ACCEPT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_ACCEPT_BIT
]);
222 if (EnumReq
.PollEvents
&
223 (AFD_EVENT_CONNECT
| AFD_EVENT_CONNECT_FAIL
)) {
224 lpNetworkEvents
->lNetworkEvents
|= FD_CONNECT
;
225 lpNetworkEvents
->iErrorCode
[FD_CONNECT_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CONNECT_BIT
]);
228 if (EnumReq
.PollEvents
&
229 (AFD_EVENT_DISCONNECT
| AFD_EVENT_ABORT
| AFD_EVENT_CLOSE
)) {
230 lpNetworkEvents
->lNetworkEvents
|= FD_CLOSE
;
231 lpNetworkEvents
->iErrorCode
[FD_CLOSE_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_CLOSE_BIT
]);
234 if (EnumReq
.PollEvents
& AFD_EVENT_QOS
) {
235 lpNetworkEvents
->lNetworkEvents
|= FD_QOS
;
236 lpNetworkEvents
->iErrorCode
[FD_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_QOS_BIT
]);
239 if (EnumReq
.PollEvents
& AFD_EVENT_GROUP_QOS
) {
240 lpNetworkEvents
->lNetworkEvents
|= FD_GROUP_QOS
;
241 lpNetworkEvents
->iErrorCode
[FD_GROUP_QOS_BIT
] = TranslateNtStatusError(EnumReq
.EventStatus
[FD_GROUP_QOS_BIT
]);
246 return MsafdReturnWithErrno(STATUS_SUCCESS
, lpErrno
, 0, NULL
);