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 int 16 WSPAPI 17 WSPEventSelect( 18 IN SOCKET Handle, 19 IN WSAEVENT hEventObject, 20 IN long lNetworkEvents, 21 OUT LPINT lpErrno) 22 { 23 IO_STATUS_BLOCK IOSB; 24 AFD_EVENT_SELECT_INFO EventSelectInfo; 25 PSOCKET_INFORMATION Socket = NULL; 26 NTSTATUS Status; 27 BOOLEAN BlockMode; 28 HANDLE SockEvent; 29 30 TRACE("WSPEventSelect (%lx) %lx %lx\n", Handle, hEventObject, lNetworkEvents); 31 32 /* Get the Socket Structure associate to this Socket*/ 33 Socket = GetSocketStructure(Handle); 34 if (!Socket) 35 { 36 if (lpErrno) *lpErrno = WSAENOTSOCK; 37 return SOCKET_ERROR; 38 } 39 40 Status = NtCreateEvent(&SockEvent, EVENT_ALL_ACCESS, 41 NULL, SynchronizationEvent, FALSE); 42 43 if (!NT_SUCCESS(Status)) return SOCKET_ERROR; 44 45 /* Set Socket to Non-Blocking */ 46 BlockMode = TRUE; 47 SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL, NULL, NULL, NULL); 48 Socket->SharedData->NonBlocking = TRUE; 49 50 /* Deactivate Async Select if there is one */ 51 if (Socket->EventObject) { 52 Socket->SharedData->hWnd = NULL; 53 Socket->SharedData->wMsg = 0; 54 Socket->SharedData->AsyncEvents = 0; 55 Socket->SharedData->SequenceNumber++; // This will kill Async Select after the next completion 56 } 57 58 /* Set Structure Info */ 59 EventSelectInfo.EventObject = hEventObject; 60 EventSelectInfo.Events = 0; 61 62 /* Set Events to wait for */ 63 if (lNetworkEvents & FD_READ) { 64 EventSelectInfo.Events |= AFD_EVENT_RECEIVE; 65 } 66 67 if (lNetworkEvents & FD_WRITE) { 68 EventSelectInfo.Events |= AFD_EVENT_SEND; 69 } 70 71 if (lNetworkEvents & FD_OOB) { 72 EventSelectInfo.Events |= AFD_EVENT_OOB_RECEIVE; 73 } 74 75 if (lNetworkEvents & FD_ACCEPT) { 76 EventSelectInfo.Events |= AFD_EVENT_ACCEPT; 77 } 78 79 if (lNetworkEvents & FD_CONNECT) { 80 EventSelectInfo.Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL; 81 } 82 83 if (lNetworkEvents & FD_CLOSE) { 84 EventSelectInfo.Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE; 85 } 86 87 if (lNetworkEvents & FD_QOS) { 88 EventSelectInfo.Events |= AFD_EVENT_QOS; 89 } 90 91 if (lNetworkEvents & FD_GROUP_QOS) { 92 EventSelectInfo.Events |= AFD_EVENT_GROUP_QOS; 93 } 94 95 /* Send IOCTL */ 96 Status = NtDeviceIoControlFile((HANDLE)Handle, 97 SockEvent, 98 NULL, 99 NULL, 100 &IOSB, 101 IOCTL_AFD_EVENT_SELECT, 102 &EventSelectInfo, 103 sizeof(EventSelectInfo), 104 NULL, 105 0); 106 107 /* Wait for return */ 108 if (Status == STATUS_PENDING) { 109 WaitForSingleObject(SockEvent, INFINITE); 110 Status = IOSB.Status; 111 } 112 113 NtClose (SockEvent); 114 115 if (Status != STATUS_SUCCESS) 116 { 117 ERR("Got status 0x%08x.\n", Status); 118 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); 119 } 120 121 /* Set Socket Data*/ 122 Socket->EventObject = hEventObject; 123 Socket->NetworkEvents = lNetworkEvents; 124 125 TRACE("Leaving\n"); 126 127 return 0; 128 } 129 130 131 INT 132 WSPAPI 133 WSPEnumNetworkEvents( 134 IN SOCKET Handle, 135 IN WSAEVENT hEventObject, 136 OUT LPWSANETWORKEVENTS lpNetworkEvents, 137 OUT LPINT lpErrno) 138 { 139 AFD_ENUM_NETWORK_EVENTS_INFO EnumReq; 140 IO_STATUS_BLOCK IOSB; 141 PSOCKET_INFORMATION Socket = NULL; 142 NTSTATUS Status; 143 HANDLE SockEvent; 144 145 TRACE("Called (lpNetworkEvents %x)\n", lpNetworkEvents); 146 147 /* Get the Socket Structure associate to this Socket*/ 148 Socket = GetSocketStructure(Handle); 149 if (!Socket) 150 { 151 if (lpErrno) *lpErrno = WSAENOTSOCK; 152 return SOCKET_ERROR; 153 } 154 if (!lpNetworkEvents) 155 { 156 if (lpErrno) *lpErrno = WSAEFAULT; 157 return SOCKET_ERROR; 158 } 159 160 Status = NtCreateEvent(&SockEvent, EVENT_ALL_ACCESS, 161 NULL, SynchronizationEvent, FALSE); 162 163 if( !NT_SUCCESS(Status) ) { 164 ERR("Could not make an event %x\n", Status); 165 return SOCKET_ERROR; 166 } 167 168 EnumReq.Event = hEventObject; 169 170 /* Send IOCTL */ 171 Status = NtDeviceIoControlFile((HANDLE)Handle, 172 SockEvent, 173 NULL, 174 NULL, 175 &IOSB, 176 IOCTL_AFD_ENUM_NETWORK_EVENTS, 177 &EnumReq, 178 sizeof(EnumReq), 179 NULL, 180 0); 181 182 /* Wait for return */ 183 if (Status == STATUS_PENDING) { 184 WaitForSingleObject(SockEvent, INFINITE); 185 Status = IOSB.Status; 186 } 187 188 NtClose (SockEvent); 189 190 if (Status != STATUS_SUCCESS) 191 { 192 ERR("Status 0x%08x", Status); 193 return MsafdReturnWithErrno(Status, lpErrno, 0, NULL); 194 } 195 196 lpNetworkEvents->lNetworkEvents = 0; 197 198 /* Set Events to wait for */ 199 if (EnumReq.PollEvents & AFD_EVENT_RECEIVE) { 200 lpNetworkEvents->lNetworkEvents |= FD_READ; 201 lpNetworkEvents->iErrorCode[FD_READ_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_READ_BIT]); 202 } 203 204 if (EnumReq.PollEvents & AFD_EVENT_SEND) { 205 lpNetworkEvents->lNetworkEvents |= FD_WRITE; 206 lpNetworkEvents->iErrorCode[FD_WRITE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_WRITE_BIT]); 207 } 208 209 if (EnumReq.PollEvents & AFD_EVENT_OOB_RECEIVE) { 210 lpNetworkEvents->lNetworkEvents |= FD_OOB; 211 lpNetworkEvents->iErrorCode[FD_OOB_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_OOB_BIT]); 212 } 213 214 if (EnumReq.PollEvents & AFD_EVENT_ACCEPT) { 215 lpNetworkEvents->lNetworkEvents |= FD_ACCEPT; 216 lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_ACCEPT_BIT]); 217 } 218 219 if (EnumReq.PollEvents & 220 (AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL)) { 221 lpNetworkEvents->lNetworkEvents |= FD_CONNECT; 222 lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CONNECT_BIT]); 223 } 224 225 if (EnumReq.PollEvents & 226 (AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT | AFD_EVENT_CLOSE)) { 227 lpNetworkEvents->lNetworkEvents |= FD_CLOSE; 228 lpNetworkEvents->iErrorCode[FD_CLOSE_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_CLOSE_BIT]); 229 } 230 231 if (EnumReq.PollEvents & AFD_EVENT_QOS) { 232 lpNetworkEvents->lNetworkEvents |= FD_QOS; 233 lpNetworkEvents->iErrorCode[FD_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_QOS_BIT]); 234 } 235 236 if (EnumReq.PollEvents & AFD_EVENT_GROUP_QOS) { 237 lpNetworkEvents->lNetworkEvents |= FD_GROUP_QOS; 238 lpNetworkEvents->iErrorCode[FD_GROUP_QOS_BIT] = TranslateNtStatusError(EnumReq.EventStatus[FD_GROUP_QOS_BIT]); 239 } 240 241 TRACE("Leaving\n"); 242 243 return MsafdReturnWithErrno(STATUS_SUCCESS, lpErrno, 0, NULL); 244 } 245 246 /* EOF */ 247