d79fe20019e0dc0bf214a86a46b3c7565056e1ad
[reactos.git] / reactos / dll / win32 / msafd / misc / event.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver DLL
4 * FILE: misc/event.c
5 * PURPOSE: Event handling
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Alex Ionescu (alex@relsoft.net)
8 * REVISIONS:
9 * CSH 15/06-2001 Created
10 * Alex 16/07/2004 - Complete Rewrite
11 */
12
13 #include <msafd.h>
14
15 #include <debug.h>
16
17 int
18 WSPAPI
19 WSPEventSelect(
20 SOCKET Handle,
21 WSAEVENT hEventObject,
22 long lNetworkEvents,
23 LPINT lpErrno)
24 {
25 IO_STATUS_BLOCK IOSB;
26 AFD_EVENT_SELECT_INFO EventSelectInfo;
27 PSOCKET_INFORMATION Socket = NULL;
28 NTSTATUS Status;
29 ULONG BlockMode;
30 HANDLE SockEvent;
31
32 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
33 NULL, 1, FALSE );
34
35 if( !NT_SUCCESS(Status) ) return -1;
36
37 /* Get the Socket Structure associate to this Socket*/
38 Socket = GetSocketStructure(Handle);
39
40 /* Set Socket to Non-Blocking */
41 BlockMode = 1;
42 SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL);
43 Socket->SharedData.NonBlocking = TRUE;
44
45 /* Deactivate Async Select if there is one */
46 if (Socket->EventObject) {
47 Socket->SharedData.hWnd = NULL;
48 Socket->SharedData.wMsg = 0;
49 Socket->SharedData.AsyncEvents = 0;
50 Socket->SharedData.SequenceNumber++; // This will kill Async Select after the next completion
51 }
52
53 /* Set Structure Info */
54 EventSelectInfo.EventObject = hEventObject;
55 EventSelectInfo.Events = 0;
56
57 /* Set Events to wait for */
58 if (lNetworkEvents & FD_READ) {
59 EventSelectInfo.Events |= AFD_EVENT_RECEIVE;
60 }
61
62 if (lNetworkEvents & FD_WRITE) {
63 EventSelectInfo.Events |= AFD_EVENT_SEND;
64 }
65
66 if (lNetworkEvents & FD_OOB) {
67 EventSelectInfo.Events |= AFD_EVENT_OOB_RECEIVE;
68 }
69
70 if (lNetworkEvents & FD_ACCEPT) {
71 EventSelectInfo.Events |= AFD_EVENT_ACCEPT;
72 }
73
74 if (lNetworkEvents & FD_CONNECT) {
75 EventSelectInfo.Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL;
76 }
77
78 if (lNetworkEvents & FD_CLOSE) {
79 EventSelectInfo.Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE;
80 }
81
82 if (lNetworkEvents & FD_QOS) {
83 EventSelectInfo.Events |= AFD_EVENT_QOS;
84 }
85
86 if (lNetworkEvents & FD_GROUP_QOS) {
87 EventSelectInfo.Events |= AFD_EVENT_GROUP_QOS;
88 }
89
90 /* Send IOCTL */
91 Status = NtDeviceIoControlFile((HANDLE)Handle,
92 SockEvent,
93 NULL,
94 NULL,
95 &IOSB,
96 IOCTL_AFD_EVENT_SELECT,
97 &EventSelectInfo,
98 sizeof(EventSelectInfo),
99 NULL,
100 0);
101
102 AFD_DbgPrint(MID_TRACE,("AFD: %x\n", Status));
103
104 /* Wait for return */
105 if (Status == STATUS_PENDING) {
106 WaitForSingleObject(SockEvent, INFINITE);
107 Status = IOSB.Status;
108 }
109
110 AFD_DbgPrint(MID_TRACE,("Waited\n"));
111
112 NtClose( SockEvent );
113
114 if (Status != STATUS_SUCCESS)
115 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
116
117 AFD_DbgPrint(MID_TRACE,("Closed event\n"));
118
119 /* Set Socket Data*/
120 Socket->EventObject = hEventObject;
121 Socket->NetworkEvents = lNetworkEvents;
122
123 AFD_DbgPrint(MID_TRACE,("Leaving\n"));
124
125 return 0;
126 }
127
128
129 INT
130 WSPAPI
131 WSPEnumNetworkEvents(
132 IN SOCKET Handle,
133 IN WSAEVENT hEventObject,
134 OUT LPWSANETWORKEVENTS lpNetworkEvents,
135 OUT LPINT lpErrno)
136 {
137 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq;
138 IO_STATUS_BLOCK IOSB;
139 PSOCKET_INFORMATION Socket = NULL;
140 NTSTATUS Status;
141 HANDLE SockEvent;
142
143 AFD_DbgPrint(MID_TRACE,("Called (lpNetworkEvents %x)\n", lpNetworkEvents));
144
145 Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
146 NULL, 1, FALSE );
147
148 if( !NT_SUCCESS(Status) ) {
149 AFD_DbgPrint(MID_TRACE,("Could not make an event %x\n", Status));
150 return -1;
151 }
152
153 /* Get the Socket Structure associate to this Socket*/
154 Socket = GetSocketStructure(Handle);
155
156 EnumReq.Event = hEventObject;
157
158 /* Send IOCTL */
159 Status = NtDeviceIoControlFile((HANDLE)Handle,
160 SockEvent,
161 NULL,
162 NULL,
163 &IOSB,
164 IOCTL_AFD_ENUM_NETWORK_EVENTS,
165 &EnumReq,
166 sizeof(EnumReq),
167 NULL,
168 0);
169
170 AFD_DbgPrint(MID_TRACE,("AFD: %x\n", Status));
171
172 /* Wait for return */
173 if (Status == STATUS_PENDING) {
174 WaitForSingleObject(SockEvent, INFINITE);
175 Status = IOSB.Status;
176 }
177
178 AFD_DbgPrint(MID_TRACE,("Waited\n"));
179
180 NtClose( SockEvent );
181
182 if (Status != STATUS_SUCCESS)
183 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
184
185 AFD_DbgPrint(MID_TRACE,("Closed event\n"));
186 AFD_DbgPrint(MID_TRACE,("About to touch struct at %x (%d)\n",
187 lpNetworkEvents, sizeof(*lpNetworkEvents)));
188
189 lpNetworkEvents->lNetworkEvents = 0;
190
191 AFD_DbgPrint(MID_TRACE,("Zeroed struct\n"));
192
193 /* Set Events to wait for */
194 if (EnumReq.PollEvents & AFD_EVENT_RECEIVE) {
195 lpNetworkEvents->lNetworkEvents |= FD_READ;
196 lpNetworkEvents->iErrorCode[FD_READ_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_READ_BIT]);
197 }
198
199 if (EnumReq.PollEvents & AFD_EVENT_SEND) {
200 lpNetworkEvents->lNetworkEvents |= FD_WRITE;
201 lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_WRITE_BIT]);
202 }
203
204 if (EnumReq.PollEvents & AFD_EVENT_OOB_RECEIVE) {
205 lpNetworkEvents->lNetworkEvents |= FD_OOB;
206 lpNetworkEvents->iErrorCode[FD_OOB_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_OOB_BIT]);
207 }
208
209 if (EnumReq.PollEvents & AFD_EVENT_ACCEPT) {
210 lpNetworkEvents->lNetworkEvents |= FD_ACCEPT;
211 lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_ACCEPT_BIT]);
212 }
213
214 if (EnumReq.PollEvents &
215 (AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL)) {
216 lpNetworkEvents->lNetworkEvents |= FD_CONNECT;
217 lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CONNECT_BIT]);
218 }
219
220 if (EnumReq.PollEvents &
221 (AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE)) {
222 lpNetworkEvents->lNetworkEvents |= FD_CLOSE;
223 lpNetworkEvents->iErrorCode[FD_CLOSE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CLOSE_BIT]);
224 }
225
226 if (EnumReq.PollEvents & AFD_EVENT_QOS) {
227 lpNetworkEvents->lNetworkEvents |= FD_QOS;
228 lpNetworkEvents->iErrorCode[FD_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_QOS_BIT]);
229 }
230
231 if (EnumReq.PollEvents & AFD_EVENT_GROUP_QOS) {
232 lpNetworkEvents->lNetworkEvents |= FD_GROUP_QOS;
233 lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_GROUP_QOS_BIT]);
234 }
235
236 AFD_DbgPrint(MID_TRACE,("Leaving\n"));
237
238 return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, NULL);
239 }
240
241 /* EOF */