0208ac5f5cdcbfb67d3835d4a24af2bbb1dc31cb
[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: 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)
8 * REVISIONS:
9 * CSH 15/06-2001 Created
10 * Alex 16/07/2004 - Complete Rewrite
11 */
12
13 #include <msafd.h>
14
15 #include <wine/debug.h>
16 WINE_DEFAULT_DEBUG_CHANNEL(msafd);
17
18 int
19 WSPAPI
20 WSPEventSelect(
21 SOCKET Handle,
22 WSAEVENT hEventObject,
23 long lNetworkEvents,
24 LPINT lpErrno)
25 {
26 IO_STATUS_BLOCK IOSB;
27 AFD_EVENT_SELECT_INFO EventSelectInfo;
28 PSOCKET_INFORMATION Socket = NULL;
29 NTSTATUS Status;
30 BOOLEAN BlockMode;
31 HANDLE SockEvent;
32
33 Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS,
34 NULL, 1, FALSE );
35
36 if( !NT_SUCCESS(Status) ) return -1;
37
38 /* Get the Socket Structure associate to this Socket*/
39 Socket = GetSocketStructure(Handle);
40 if (!Socket)
41 {
42 NtClose(SockEvent);
43 *lpErrno = WSAENOTSOCK;
44 return SOCKET_ERROR;
45 }
46
47 /* Set Socket to Non-Blocking */
48 BlockMode = TRUE;
49 SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL);
50 Socket->SharedData->NonBlocking = TRUE;
51
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
58 }
59
60 /* Set Structure Info */
61 EventSelectInfo.EventObject = hEventObject;
62 EventSelectInfo.Events = 0;
63
64 /* Set Events to wait for */
65 if (lNetworkEvents & FD_READ) {
66 EventSelectInfo.Events |= AFD_EVENT_RECEIVE;
67 }
68
69 if (lNetworkEvents & FD_WRITE) {
70 EventSelectInfo.Events |= AFD_EVENT_SEND;
71 }
72
73 if (lNetworkEvents & FD_OOB) {
74 EventSelectInfo.Events |= AFD_EVENT_OOB_RECEIVE;
75 }
76
77 if (lNetworkEvents & FD_ACCEPT) {
78 EventSelectInfo.Events |= AFD_EVENT_ACCEPT;
79 }
80
81 if (lNetworkEvents & FD_CONNECT) {
82 EventSelectInfo.Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL;
83 }
84
85 if (lNetworkEvents & FD_CLOSE) {
86 EventSelectInfo.Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE;
87 }
88
89 if (lNetworkEvents & FD_QOS) {
90 EventSelectInfo.Events |= AFD_EVENT_QOS;
91 }
92
93 if (lNetworkEvents & FD_GROUP_QOS) {
94 EventSelectInfo.Events |= AFD_EVENT_GROUP_QOS;
95 }
96
97 /* Send IOCTL */
98 Status = NtDeviceIoControlFile((HANDLE)Handle,
99 SockEvent,
100 NULL,
101 NULL,
102 &IOSB,
103 IOCTL_AFD_EVENT_SELECT,
104 &EventSelectInfo,
105 sizeof(EventSelectInfo),
106 NULL,
107 0);
108
109 TRACE("AFD: %x\n", Status);
110
111 /* Wait for return */
112 if (Status == STATUS_PENDING) {
113 WaitForSingleObject(SockEvent, INFINITE);
114 Status = IOSB.Status;
115 }
116
117 TRACE("Waited\n");
118
119 NtClose( SockEvent );
120
121 if (Status != STATUS_SUCCESS)
122 {
123 ERR("Got status 0x%08x.\n", Status);
124 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
125 }
126
127 TRACE("Closed event\n");
128
129 /* Set Socket Data*/
130 Socket->EventObject = hEventObject;
131 Socket->NetworkEvents = lNetworkEvents;
132
133 TRACE("Leaving\n");
134
135 return 0;
136 }
137
138
139 INT
140 WSPAPI
141 WSPEnumNetworkEvents(
142 IN SOCKET Handle,
143 IN WSAEVENT hEventObject,
144 OUT LPWSANETWORKEVENTS lpNetworkEvents,
145 OUT LPINT lpErrno)
146 {
147 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq;
148 IO_STATUS_BLOCK IOSB;
149 PSOCKET_INFORMATION Socket = NULL;
150 NTSTATUS Status;
151 HANDLE SockEvent;
152
153 TRACE("Called (lpNetworkEvents %x)\n", lpNetworkEvents);
154
155 Status = NtCreateEvent( &SockEvent, EVENT_ALL_ACCESS,
156 NULL, 1, FALSE );
157
158 if( !NT_SUCCESS(Status) ) {
159 ERR("Could not make an event %x\n", Status);
160 return -1;
161 }
162
163 /* Get the Socket Structure associate to this Socket*/
164 Socket = GetSocketStructure(Handle);
165 if (!Socket)
166 {
167 NtClose(SockEvent);
168 *lpErrno = WSAENOTSOCK;
169 return SOCKET_ERROR;
170 }
171
172 EnumReq.Event = hEventObject;
173
174 /* Send IOCTL */
175 Status = NtDeviceIoControlFile((HANDLE)Handle,
176 SockEvent,
177 NULL,
178 NULL,
179 &IOSB,
180 IOCTL_AFD_ENUM_NETWORK_EVENTS,
181 &EnumReq,
182 sizeof(EnumReq),
183 NULL,
184 0);
185
186 TRACE("AFD: %x\n", Status);
187
188 /* Wait for return */
189 if (Status == STATUS_PENDING) {
190 WaitForSingleObject(SockEvent, INFINITE);
191 Status = IOSB.Status;
192 }
193
194 TRACE("Waited\n");
195
196 NtClose( SockEvent );
197
198 if (Status != STATUS_SUCCESS)
199 {
200 ERR("Status 0x%08x", Status);
201 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL);
202 }
203
204 TRACE("Closed event\n");
205 TRACE("About to touch struct at %x (%d)\n", lpNetworkEvents, sizeof(*lpNetworkEvents));
206
207 lpNetworkEvents->lNetworkEvents = 0;
208
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]);
213 }
214
215 if (EnumReq.PollEvents & AFD_EVENT_SEND) {
216 lpNetworkEvents->lNetworkEvents |= FD_WRITE;
217 lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_WRITE_BIT]);
218 }
219
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]);
223 }
224
225 if (EnumReq.PollEvents & AFD_EVENT_ACCEPT) {
226 lpNetworkEvents->lNetworkEvents |= FD_ACCEPT;
227 lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_ACCEPT_BIT]);
228 }
229
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]);
234 }
235
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]);
240 }
241
242 if (EnumReq.PollEvents & AFD_EVENT_QOS) {
243 lpNetworkEvents->lNetworkEvents |= FD_QOS;
244 lpNetworkEvents->iErrorCode[FD_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_QOS_BIT]);
245 }
246
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]);
250 }
251
252 TRACE("Leaving\n");
253
254 return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, NULL);
255 }
256
257 /* EOF */