ReactOS 0.4.15-dev-8102-g108db8f
event.c File Reference
#include "precomp.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "lwip/api.h"
#include <lwip_glue/lwip_glue.h>
Include dependency graph for event.c:

Go to the source code of this file.

Functions

static VOID BucketCompletionWorker (PVOID Context)
 
VOID CompleteBucket (PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEAN Synchronous)
 
VOID FlushReceiveQueue (PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 
VOID FlushSendQueue (PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 
VOID FlushShutdownQueue (PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 
VOID FlushConnectQueue (PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 
VOID FlushListenQueue (PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 
VOID FlushAllQueues (PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
 
VOID TCPFinEventHandler (void *arg, const err_t err)
 
VOID TCPAcceptEventHandler (void *arg, PTCP_PCB newpcb)
 
VOID TCPSendEventHandler (void *arg, const u16_t space)
 
VOID TCPRecvEventHandler (void *arg)
 
VOID TCPConnectEventHandler (void *arg, const err_t err)
 

Variables

NPAGED_LOOKASIDE_LIST TdiBucketLookasideList
 

Function Documentation

◆ BucketCompletionWorker()

static VOID BucketCompletionWorker ( PVOID  Context)
static

Definition at line 23 of file event.c.

24{
27
29
30 Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
31
33
34 ExFreeToNPagedLookasideList(&TdiBucketLookasideList, Bucket);
35}
NPAGED_LOOKASIDE_LIST TdiBucketLookasideList
Definition: tcp.c:26
pRequest Complete(RequestStatus)
VOID(* PTCP_COMPLETION_ROUTINE)(PVOID Context, NTSTATUS Status, ULONG Count)
Definition: tcp.h:11
NTSTATUS Status
Definition: titypes.h:233
ULONG Information
Definition: titypes.h:234
TDI_REQUEST Request
Definition: titypes.h:232
struct _CONNECTION_ENDPOINT * AssociatedEndpoint
Definition: titypes.h:231
PVOID RequestContext
Definition: tdi.h:55
PVOID RequestNotifyObject
Definition: tdi.h:54
#define DereferenceObject(Object)
Definition: titypes.h:24
struct _TDI_BUCKET * PTDI_BUCKET

Referenced by CompleteBucket().

◆ CompleteBucket()

VOID CompleteBucket ( PCONNECTION_ENDPOINT  Connection,
PTDI_BUCKET  Bucket,
const BOOLEAN  Synchronous 
)

Definition at line 38 of file event.c.

39{
40 ReferenceObject(Connection);
41 Bucket->AssociatedEndpoint = Connection;
42 if (Synchronous)
43 {
45 }
46 else
47 {
49 }
50}
static VOID BucketCompletionWorker(PVOID Context)
Definition: event.c:23
#define ReferenceObject(Object)
Definition: titypes.h:14
BOOLEAN ChewCreate(VOID(*Worker)(PVOID), PVOID WorkerContext)
Definition: workqueue.c:61

Referenced by DisconnectWorker(), FlushConnectQueue(), FlushListenQueue(), FlushReceiveQueue(), FlushSendQueue(), FlushShutdownQueue(), TCPAcceptEventHandler(), TCPConnectEventHandler(), TCPRecvEventHandler(), and TCPSendEventHandler().

◆ FlushAllQueues()

VOID FlushAllQueues ( PCONNECTION_ENDPOINT  Connection,
NTSTATUS  Status 
)

Definition at line 157 of file event.c.

158{
159 // flush receive queue
160 FlushReceiveQueue(Connection, Status);
161
162 /* We completed the reads successfully but we need to return failure now */
163 if (Status == STATUS_SUCCESS)
164 {
166 }
167
168 // flush listen queue
169 FlushListenQueue(Connection, Status);
170
171 // flush send queue
172 FlushSendQueue(Connection, Status);
173
174 // flush connect queue
175 FlushConnectQueue(Connection, Status);
176
177 // flush shutdown queue
178 FlushShutdownQueue(Connection, Status);
179}
VOID FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Definition: event.c:116
VOID FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Definition: event.c:95
VOID FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Definition: event.c:136
VOID FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Definition: event.c:53
VOID FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Definition: event.c:74
Status
Definition: gdiplustypes.h:25
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by TCPClose(), and TCPFinEventHandler().

◆ FlushConnectQueue()

VOID FlushConnectQueue ( PCONNECTION_ENDPOINT  Connection,
const NTSTATUS  Status 
)

Definition at line 116 of file event.c.

117{
118 PTDI_BUCKET Bucket;
120
121 ASSERT_TCPIP_OBJECT_LOCKED(Connection);
122
123 while (!IsListEmpty(&Connection->ConnectRequest))
124 {
125 Entry = RemoveHeadList(&Connection->ConnectRequest);
127
128 Bucket->Status = Status;
129 Bucket->Information = 0;
130
131 CompleteBucket(Connection, Bucket, FALSE);
132 }
133}
#define FALSE
Definition: types.h:117
VOID CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEAN Synchronous)
Definition: event.c:38
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY ConnectRequest
Definition: titypes.h:250
Definition: typedefs.h:120
#define ASSERT_TCPIP_OBJECT_LOCKED(Object)
Definition: titypes.h:51
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by FlushAllQueues().

◆ FlushListenQueue()

VOID FlushListenQueue ( PCONNECTION_ENDPOINT  Connection,
const NTSTATUS  Status 
)

Definition at line 136 of file event.c.

137{
138 PTDI_BUCKET Bucket;
140
141 ASSERT_TCPIP_OBJECT_LOCKED(Connection);
142
143 while (!IsListEmpty(&Connection->ListenRequest))
144 {
145 Entry = RemoveHeadList(&Connection->ListenRequest);
147
148 Bucket->Status = Status;
149 Bucket->Information = 0;
150
152 CompleteBucket(Connection, Bucket, FALSE);
153 }
154}
LIST_ENTRY ListenRequest
Definition: titypes.h:251

Referenced by FlushAllQueues().

◆ FlushReceiveQueue()

VOID FlushReceiveQueue ( PCONNECTION_ENDPOINT  Connection,
const NTSTATUS  Status 
)

Definition at line 53 of file event.c.

54{
55 PTDI_BUCKET Bucket;
57
59
60 while (!IsListEmpty(&Connection->ReceiveRequest))
61 {
62 Entry = RemoveHeadList(&Connection->ReceiveRequest);
63
65
66 Bucket->Information = 0;
67 Bucket->Status = Status;
68
69 CompleteBucket(Connection, Bucket, FALSE);
70 }
71}
LIST_ENTRY ReceiveRequest
Definition: titypes.h:252

Referenced by FlushAllQueues(), and TCPDisconnect().

◆ FlushSendQueue()

VOID FlushSendQueue ( PCONNECTION_ENDPOINT  Connection,
const NTSTATUS  Status 
)

Definition at line 74 of file event.c.

75{
76 PTDI_BUCKET Bucket;
78
80
81 while (!IsListEmpty(&Connection->SendRequest))
82 {
83 Entry = RemoveHeadList(&Connection->SendRequest);
84
86
87 Bucket->Information = 0;
88 Bucket->Status = Status;
89
90 CompleteBucket(Connection, Bucket, FALSE);
91 }
92}
LIST_ENTRY SendRequest
Definition: titypes.h:253

Referenced by FlushAllQueues(), and TCPDisconnect().

◆ FlushShutdownQueue()

VOID FlushShutdownQueue ( PCONNECTION_ENDPOINT  Connection,
const NTSTATUS  Status 
)

Definition at line 95 of file event.c.

96{
97 PTDI_BUCKET Bucket;
99
100 ASSERT_TCPIP_OBJECT_LOCKED(Connection);
101
102 while (!IsListEmpty(&Connection->ShutdownRequest))
103 {
104 Entry = RemoveHeadList(&Connection->ShutdownRequest);
105
107
108 Bucket->Information = 0;
109 Bucket->Status = Status;
110
111 CompleteBucket(Connection, Bucket, FALSE);
112 }
113}
LIST_ENTRY ShutdownRequest
Definition: titypes.h:254

Referenced by FlushAllQueues(), TCPDisconnect(), and TCPSendEventHandler().

◆ TCPAcceptEventHandler()

VOID TCPAcceptEventHandler ( void arg,
PTCP_PCB  newpcb 
)

Definition at line 231 of file event.c.

232{
234 PTDI_BUCKET Bucket;
236 PIRP Irp;
238
239 LockObject(Connection);
240
241 while (!IsListEmpty(&Connection->ListenRequest))
242 {
244
245 Entry = RemoveHeadList(&Connection->ListenRequest);
246
248
249 Irp = Bucket->Request.RequestContext;
251
252 TI_DbgPrint(DEBUG_TCP,("[IP, TCPAcceptEventHandler] Getting the socket\n"));
253
256
257 TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n", Status));
258
259 Bucket->Status = Status;
260 Bucket->Information = 0;
261
262 if (Status == STATUS_SUCCESS)
263 {
265
266 /* sanity assert...this should never be in anything else but a CLOSED state */
267 ASSERT( ((PTCP_PCB)Bucket->AssociatedEndpoint->SocketContext)->state == CLOSED );
268
269 /* free socket context created in FileOpenConnection, as we're using a new one */
271
272 /* free previously created socket context (we don't use it, we use newpcb) */
273 Bucket->AssociatedEndpoint->SocketContext = newpcb;
274
276
277 LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext, Bucket->AssociatedEndpoint);
278 }
279
281
282 CompleteBucket(Connection, Bucket, FALSE);
283
284 if (Status == STATUS_SUCCESS)
285 {
286 break;
287 }
288 }
289
290 UnlockObject(Connection);
291}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define DEBUG_TCP
Definition: debug.h:28
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
NTSTATUS TCPCheckPeerForAccept(PVOID Context, PTDI_REQUEST_KERNEL Request)
Definition: accept.c:17
struct tcp_pcb * PTCP_PCB
Definition: lwip_glue.h:15
err_t LibTCPClose(PCONNECTION_ENDPOINT Connection, const int safe, const int callback)
Definition: tcp.c:798
void LibTCPAccept(PTCP_PCB pcb, struct tcp_pcb *listen_pcb, void *arg)
Definition: tcp.c:830
#define ASSERT(a)
Definition: mode.c:44
union _IO_STACK_LOCATION::@1567 Parameters
#define UnlockObject(Object)
Definition: titypes.h:44
#define LockObject(Object)
Definition: titypes.h:34
struct _CONNECTION_ENDPOINT * PCONNECTION_ENDPOINT

Referenced by InternalAcceptEventHandler().

◆ TCPConnectEventHandler()

VOID TCPConnectEventHandler ( void arg,
const err_t  err 
)

Definition at line 420 of file event.c.

421{
423 PTDI_BUCKET Bucket;
425
426 LockObject(Connection);
427
428 while (!IsListEmpty(&Connection->ConnectRequest))
429 {
430 Entry = RemoveHeadList(&Connection->ConnectRequest);
431
433
434 Bucket->Status = TCPTranslateError(err);
435 Bucket->Information = 0;
436
437 CompleteBucket(Connection, Bucket, FALSE);
438 }
439
440 UnlockObject(Connection);
441}
NTSTATUS TCPTranslateError(const INT8 err)
Definition: tcp.c:267
#define err(...)

Referenced by InternalConnectEventHandler().

◆ TCPFinEventHandler()

VOID TCPFinEventHandler ( void arg,
const err_t  err 
)

Definition at line 182 of file event.c.

183{
184 PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg, LastConnection;
186
187 ASSERT(Connection->SocketContext == NULL);
188 ASSERT(Connection->AddressFile);
189 ASSERT(err != ERR_OK);
190
191 LockObject(Connection);
192
193 /* Complete all outstanding requests now */
194 FlushAllQueues(Connection, Status);
195
196 LockObject(Connection->AddressFile);
197
198 /* Unlink this connection from the address file */
199 if (Connection->AddressFile->Connection == Connection)
200 {
201 Connection->AddressFile->Connection = Connection->Next;
202 DereferenceObject(Connection);
203 }
204 else if (Connection->AddressFile->Listener == Connection)
205 {
206 Connection->AddressFile->Listener = NULL;
207 DereferenceObject(Connection);
208 }
209 else
210 {
211 LastConnection = Connection->AddressFile->Connection;
212 while (LastConnection->Next != Connection && LastConnection->Next != NULL)
213 LastConnection = LastConnection->Next;
214 if (LastConnection->Next == Connection)
215 {
216 LastConnection->Next = Connection->Next;
217 DereferenceObject(Connection);
218 }
219 }
220
221 UnlockObject(Connection->AddressFile);
222
223 /* Remove the address file from this connection */
224 DereferenceObject(Connection->AddressFile);
225 Connection->AddressFile = NULL;
226
227 UnlockObject(Connection);
228}
#define NULL
Definition: types.h:112
VOID FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
Definition: event.c:157
#define ERR_OK
Definition: err.h:52
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
struct _CONNECTION_ENDPOINT * Connection
Definition: titypes.h:131
struct _CONNECTION_ENDPOINT * Listener
Definition: titypes.h:133
PADDRESS_FILE AddressFile
Definition: titypes.h:247
struct _CONNECTION_ENDPOINT * Next
Definition: titypes.h:269

Referenced by InternalErrorEventHandler(), InternalRecvEventHandler(), LibTCPCloseCallback(), and LibTCPShutdownCallback().

◆ TCPRecvEventHandler()

VOID TCPRecvEventHandler ( void arg)

Definition at line 380 of file event.c.

381{
383 PTDI_BUCKET Bucket;
385 PIRP Irp;
386 PMDL Mdl;
388 UINT RecvLen;
389 PUCHAR RecvBuffer;
391
392 LockObject(Connection);
393
394 while(!IsListEmpty(&Connection->ReceiveRequest))
395 {
396 Entry = RemoveHeadList(&Connection->ReceiveRequest);
398
399 Irp = Bucket->Request.RequestContext;
400 Mdl = Irp->MdlAddress;
401
402 NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
403
404 Status = LibTCPGetDataFromConnectionQueue(Connection, RecvBuffer, RecvLen, &Received);
405 if (Status == STATUS_PENDING)
406 {
407 InsertHeadList(&Connection->ReceiveRequest, &Bucket->Entry);
408 break;
409 }
410
411 Bucket->Status = Status;
412 Bucket->Information = Received;
413
414 CompleteBucket(Connection, Bucket, FALSE);
415 }
416 UnlockObject(Connection);
417}
UINT Received
Definition: arping.c:40
#define InsertHeadList(ListHead, Entry)
NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHAR RecvBuffer, UINT RecvLen, UINT *Received)
Definition: tcp.c:100
unsigned int UINT
Definition: ndis.h:50
#define NdisQueryBuffer(_Buffer, _VirtualAddress, _Length)
Definition: ndis.h:3029
#define STATUS_PENDING
Definition: ntstatus.h:82
LIST_ENTRY Entry
Definition: titypes.h:230
unsigned char * PUCHAR
Definition: typedefs.h:53
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl

Referenced by InternalErrorEventHandler(), and InternalRecvEventHandler().

◆ TCPSendEventHandler()

VOID TCPSendEventHandler ( void arg,
const u16_t  space 
)

Definition at line 294 of file event.c.

295{
297 PTDI_BUCKET Bucket;
299 PIRP Irp;
301 PMDL Mdl;
302 ULONG BytesSent;
303
304 ReferenceObject(Connection);
305 LockObject(Connection);
306
307 while (!IsListEmpty(&Connection->SendRequest))
308 {
309 UINT SendLen = 0;
310 PVOID SendBuffer = 0;
311
312 Entry = RemoveHeadList(&Connection->SendRequest);
313
314 UnlockObject(Connection);
315
317
318 Irp = Bucket->Request.RequestContext;
319 Mdl = Irp->MdlAddress;
320
322 ("Getting the user buffer from %x\n", Mdl));
323
324 NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
325
327 ("Writing %d bytes to %x\n", SendLen, SendBuffer));
328
329 TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
331 (DEBUG_TCP,
332 ("Connection->SocketContext: %x\n",
333 Connection->SocketContext));
334
336 SendBuffer,
337 SendLen, &BytesSent, TRUE));
338
339 TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", BytesSent));
340
341 if( Status == STATUS_PENDING )
342 {
343 LockObject(Connection);
344 InsertHeadList(&Connection->SendRequest, &Bucket->Entry);
345 break;
346 }
347 else
348 {
350 ("Completing Send request: %x %x\n",
351 Bucket->Request, Status));
352
353 Bucket->Status = Status;
354 Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? BytesSent : 0;
355
356 CompleteBucket(Connection, Bucket, FALSE);
357 }
358
359 LockObject(Connection);
360 }
361
362 // If we completed all outstanding send requests then finish all pending shutdown requests,
363 // cancel the timer and dereference the connection
364 if (IsListEmpty(&Connection->SendRequest))
365 {
367
368 if (KeCancelTimer(&Connection->DisconnectTimer))
369 {
370 DereferenceObject(Connection);
371 }
372 }
373
374 UnlockObject(Connection);
375
376 DereferenceObject(Connection);
377}
err_t LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, u32_t *sent, const int safe)
Definition: tcp.c:557
KTIMER DisconnectTimer
Definition: titypes.h:259
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
uint32_t ULONG
Definition: typedefs.h:59

Referenced by InternalSendEventHandler().

Variable Documentation

◆ TdiBucketLookasideList