ReactOS 0.4.15-dev-7918-g2a2556c
listen.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/listen.c
5 * PURPOSE: Ancillary functions driver
6 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
7 * UPDATE HISTORY:
8 * 20040708 Created
9 */
10
11#include "afd.h"
12
14 PIRP Irp,
17 PAFD_FCB FCB = NewFileObject->FsContext;
19
20 UNREFERENCED_PARAMETER(DeviceExt);
21
23 return LostSocket( Irp );
24
25 /* Transfer the connection to the new socket, launch the opening read */
26 AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %p)\n", FCB));
27
28 FCB->Connection = Qelt->Object;
29
30 if (FCB->RemoteAddress)
31 {
33 }
34
35 FCB->RemoteAddress =
37
38 if( !FCB->RemoteAddress )
40 else
42
43 if (NT_SUCCESS(Status))
44 Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, FCB->RemoteAddress);
45
46 if (NT_SUCCESS(Status))
47 Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, FCB->RemoteAddress);
48
49 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
50}
51
53 PAFD_RECEIVED_ACCEPT_DATA ListenReceive =
54 (PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
56
57 ListenReceive->SequenceNumber = Qelt->Seq;
58
59 AFD_DbgPrint(MID_TRACE,("Giving SEQ %u to userland\n", Qelt->Seq));
60 AFD_DbgPrint(MID_TRACE,("Socket Address (K) %p (U) %p\n",
61 &ListenReceive->Address,
62 Qelt->ConnInfo->RemoteAddress));
63
65 Qelt->ConnInfo->RemoteAddress );
66
67 IPAddr = (PTA_IP_ADDRESS)&ListenReceive->Address;
68
69 AFD_DbgPrint(MID_TRACE,("IPAddr->TAAddressCount %d\n",
70 IPAddr->TAAddressCount));
71 AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressType %u\n",
72 IPAddr->Address[0].AddressType));
73 AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressLength %u\n",
74 IPAddr->Address[0].AddressLength));
75 AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_port %x\n",
76 IPAddr->Address[0].Address[0].sin_port));
77 AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_addr %x\n",
78 IPAddr->Address[0].Address[0].in_addr));
79
80 if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
81
82 Irp->IoStatus.Information = ((PCHAR)&IPAddr[1]) - ((PCHAR)ListenReceive);
83 Irp->IoStatus.Status = STATUS_SUCCESS;
86 return STATUS_SUCCESS;
87}
88
89static IO_COMPLETION_ROUTINE ListenComplete;
91 PIRP Irp,
92 PVOID Context ) {
96 PLIST_ENTRY NextIrpEntry;
97 PIRP NextIrp;
98
100
102 return STATUS_FILE_CLOSED;
103
104 ASSERT(FCB->ListenIrp.InFlightRequest == Irp);
105 FCB->ListenIrp.InFlightRequest = NULL;
106
107 if( FCB->State == SOCKET_STATE_CLOSED ) {
108 /* Cleanup our IRP queue because the FCB is being destroyed */
109 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) ) {
110 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_PREACCEPT]);
111 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
113 NextIrp->IoStatus.Information = 0;
114 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
115 (void)IoSetCancelRoutine(NextIrp, NULL);
117 }
118
119 /* Free ConnectionReturnInfo and ConnectionCallInfo */
120 if (FCB->ListenIrp.ConnectionReturnInfo)
121 {
122 ExFreePoolWithTag(FCB->ListenIrp.ConnectionReturnInfo,
124
125 FCB->ListenIrp.ConnectionReturnInfo = NULL;
126 }
127
128 if (FCB->ListenIrp.ConnectionCallInfo)
129 {
130 ExFreePoolWithTag(FCB->ListenIrp.ConnectionCallInfo,
132
133 FCB->ListenIrp.ConnectionCallInfo = NULL;
134 }
135
137 return STATUS_FILE_CLOSED;
138 }
139
140 AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
141 AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", Irp->IoStatus.Status));
142
143 if (Irp->IoStatus.Status != STATUS_SUCCESS)
144 {
146 return Irp->IoStatus.Status;
147 }
148
150 sizeof(*Qelt),
152
153 if( !Qelt ) {
155 } else {
156 UINT AddressType =
157 FCB->LocalAddress->Address[0].AddressType;
158
159 Qelt->Object = FCB->Connection;
160 Qelt->Seq = FCB->ConnSeq++;
161 AFD_DbgPrint(MID_TRACE,("Address Type: %u (RA %p)\n",
162 AddressType,
163 FCB->ListenIrp.
164 ConnectionReturnInfo->RemoteAddress));
165
166 Status = TdiBuildNullConnectionInfo( &Qelt->ConnInfo, AddressType );
167 if( NT_SUCCESS(Status) ) {
169 ( Qelt->ConnInfo->RemoteAddress,
170 FCB->ListenIrp.ConnectionReturnInfo->RemoteAddress );
171 InsertTailList( &FCB->PendingConnections, &Qelt->ListEntry );
172 }
173 }
174
175 /* Satisfy a pre-accept request if one is available */
176 if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
177 !IsListEmpty( &FCB->PendingConnections ) ) {
178 PLIST_ENTRY PendingIrp =
179 RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
180 PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
182 ( CONTAINING_RECORD( PendingIrp, IRP,
183 Tail.Overlay.ListEntry ),
185 ListEntry ) );
186 }
187
188 /* Launch new accept socket */
190
191 if (NT_SUCCESS(Status))
192 {
193 Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionCallInfo,
194 FCB->LocalAddress->Address[0].AddressType);
196
197 Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionReturnInfo,
198 FCB->LocalAddress->Address[0].AddressType);
200
201 Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
202 FCB->Connection.Object,
203 &FCB->ListenIrp.ConnectionCallInfo,
204 &FCB->ListenIrp.ConnectionReturnInfo,
206 FCB );
207
208 if (Status == STATUS_PENDING)
210 }
211
212 /* Trigger a select return if appropriate */
213 if( !IsListEmpty( &FCB->PendingConnections ) ) {
214 FCB->PollState |= AFD_EVENT_ACCEPT;
215 FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
216 PollReeval( FCB->DeviceExt, FCB->FileObject );
217 } else
218 FCB->PollState &= ~AFD_EVENT_ACCEPT;
219
221
222 return Status;
223}
224
229 PAFD_FCB FCB = FileObject->FsContext;
230 PAFD_LISTEN_DATA ListenReq;
231
233
234 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
235
236 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
237
238 if( !(ListenReq = LockRequest( Irp, IrpSp, FALSE, NULL )) )
240 0 );
241
242 if( FCB->State != SOCKET_STATE_BOUND ) {
244 AFD_DbgPrint(MIN_TRACE,("Could not listen an unbound socket\n"));
245 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
246 }
247
248 FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
249
250 AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %p\n", FCB->AddressFile.Handle));
251
253
254 AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status));
255
256 if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
257
259 ( &FCB->ListenIrp.ConnectionCallInfo,
260 FCB->LocalAddress->Address[0].AddressType );
261
263
265 ( &FCB->ListenIrp.ConnectionReturnInfo,
266 FCB->LocalAddress->Address[0].AddressType );
267
268 if (!NT_SUCCESS(Status))
269 {
270 ExFreePoolWithTag(FCB->ListenIrp.ConnectionCallInfo,
272
273 FCB->ListenIrp.ConnectionCallInfo = NULL;
275 }
276
278
279 Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
280 FCB->Connection.Object,
281 &FCB->ListenIrp.ConnectionCallInfo,
282 &FCB->ListenIrp.ConnectionReturnInfo,
284 FCB );
285
286 if( Status == STATUS_PENDING )
288
289 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
290 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
291}
292
296 PAFD_FCB FCB = FileObject->FsContext;
298
300
301 AFD_DbgPrint(MID_TRACE,("Called\n"));
302
303 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
304
305 if( !IsListEmpty( &FCB->PendingConnections ) ) {
306 PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
307
308 /* We have a pending connection ... complete this irp right away */
310 ( Irp,
312 ( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) );
313
314 AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
315
316 if ( !IsListEmpty( &FCB->PendingConnections ) )
317 {
318 FCB->PollState |= AFD_EVENT_ACCEPT;
319 FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
320 PollReeval( FCB->DeviceExt, FCB->FileObject );
321 } else
322 FCB->PollState &= ~AFD_EVENT_ACCEPT;
323
325 return Status;
326 } else if (FCB->NonBlocking) {
327 AFD_DbgPrint(MIN_TRACE,("No connection ready on a non-blocking socket\n"));
328
330 } else {
331 AFD_DbgPrint(MID_TRACE,("Holding\n"));
332
334 }
335}
336
341 PAFD_DEVICE_EXTENSION DeviceExt =
342 (PAFD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
343 PAFD_FCB FCB = FileObject->FsContext;
344 PAFD_ACCEPT_DATA AcceptData = Irp->AssociatedIrp.SystemBuffer;
345 PLIST_ENTRY PendingConn;
346
347 AFD_DbgPrint(MID_TRACE,("Called\n"));
348
349 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
350
351 FCB->EventSelectDisabled &= ~AFD_EVENT_ACCEPT;
352
353 for( PendingConn = FCB->PendingConnections.Flink;
354 PendingConn != &FCB->PendingConnections;
355 PendingConn = PendingConn->Flink ) {
356 PAFD_TDI_OBJECT_QELT PendingConnObj =
357 CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry );
358
359 AFD_DbgPrint(MID_TRACE,("Comparing Seq %u to Q %u\n",
360 AcceptData->SequenceNumber,
361 PendingConnObj->Seq));
362
363 if( PendingConnObj->Seq == AcceptData->SequenceNumber ) {
365
366 RemoveEntryList( PendingConn );
367
369 ( AcceptData->ListenHandle,
371 NULL,
374 NULL );
375
376 if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
377
379 ASSERT(NewFileObject->FsContext != FCB);
380
381 /* We have a pending connection ... complete this irp right away */
382 Status = SatisfyAccept( DeviceExt, Irp, NewFileObject, PendingConnObj );
383
385
386 AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
387
389
390 if( !IsListEmpty( &FCB->PendingConnections ) )
391 {
392 FCB->PollState |= AFD_EVENT_ACCEPT;
393 FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
394 PollReeval( FCB->DeviceExt, FCB->FileObject );
395 } else
396 FCB->PollState &= ~AFD_EVENT_ACCEPT;
397
399 return Status;
400 }
401 }
402
403 AFD_DbgPrint(MIN_TRACE,("No connection waiting\n"));
404
406}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define SOCKET_STATE_CLOSED
Definition: afd.h:82
struct _AFD_FCB * PAFD_FCB
#define TAG_AFD_TDI_CONNECTION_INFORMATION
Definition: afd.h:53
#define FUNCTION_PREACCEPT
Definition: afd.h:87
#define TAG_AFD_ACCEPT_QUEUE
Definition: afd.h:46
#define SOCKET_STATE_LISTENING
Definition: afd.h:77
#define SOCKET_STATE_BOUND
Definition: afd.h:74
struct _AFD_DEVICE_EXTENSION * PAFD_DEVICE_EXTENSION
#define TAG_AFD_TRANSPORT_ADDRESS
Definition: afd.h:39
LONG NTSTATUS
Definition: precomp.h:26
#define MIN_TRACE
Definition: debug.h:14
#define MID_TRACE
Definition: debug.h:15
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
NTSTATUS MakeSocketIntoConnection(PAFD_FCB FCB)
Definition: connect.c:259
NTSTATUS WarmSocketForConnection(PAFD_FCB FCB)
Definition: connect.c:238
static IO_COMPLETION_ROUTINE ListenComplete
Definition: listen.c:89
NTSTATUS AfdAccept(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: listen.c:337
static NTSTATUS SatisfyPreAccept(PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt)
Definition: listen.c:52
NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: listen.c:225
static NTSTATUS SatisfyAccept(PAFD_DEVICE_EXTENSION DeviceExt, PIRP Irp, PFILE_OBJECT NewFileObject, PAFD_TDI_OBJECT_QELT Qelt)
Definition: listen.c:13
NTSTATUS AfdWaitForListen(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: listen.c:293
PVOID LockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Output, KPROCESSOR_MODE *LockMode)
Definition: lock.c:24
VOID UnlockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:180
NTSTATUS LostSocket(PIRP Irp)
Definition: lock.c:387
NTSTATUS NTAPI UnlockAndMaybeComplete(PAFD_FCB FCB, NTSTATUS Status, PIRP Irp, UINT Information)
Definition: lock.c:375
VOID SocketStateUnlock(PAFD_FCB FCB)
Definition: lock.c:370
NTSTATUS LeaveIrpUntilLater(PAFD_FCB FCB, PIRP Irp, UINT Function)
Definition: lock.c:433
BOOLEAN SocketAcquireStateLock(PAFD_FCB FCB)
Definition: lock.c:360
VOID PollReeval(PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: select.c:407
NTSTATUS TdiListen(PIRP *Irp, PFILE_OBJECT ConnectionObject, PTDI_CONNECTION_INFORMATION *RequestConnectionInfo, PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Definition: tdi.c:489
#define AFD_DbgPrint(_t_, _x_)
Definition: debug.h:60
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
_Must_inspect_result_ _In_ PFILE_OBJECT NewFileObject
Definition: fsrtlfuncs.h:1357
Status
Definition: gdiplustypes.h:25
IoSetCancelRoutine(Irp, CancelRoutine)
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned int UINT
Definition: ndis.h:50
#define KernelMode
Definition: asm.h:34
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
ULONG IPAddr
Definition: pfhook.h:35
#define AFD_EVENT_ACCEPT
Definition: shared.h:210
struct _AFD_RECEIVED_ACCEPT_DATA * PAFD_RECEIVED_ACCEPT_DATA
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: afd.h:159
BOOLEAN UseDelayedAcceptance
Definition: shared.h:46
TRANSPORT_ADDRESS Address
Definition: shared.h:70
AFD_TDI_OBJECT Object
Definition: afd.h:138
PTDI_CONNECTION_INFORMATION ConnInfo
Definition: afd.h:137
LIST_ENTRY ListEntry
Definition: afd.h:135
Definition: cdstruc.h:902
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
struct _TA_ADDRESS_IP * PTA_IP_ADDRESS
NTSTATUS TdiBuildNullConnectionInfo(PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type)
Definition: tdiconn.c:171
VOID TaCopyTransportAddressInPlace(PTRANSPORT_ADDRESS Target, PTRANSPORT_ADDRESS Source)
Definition: tdiconn.c:74
NTSTATUS TdiBuildNullConnectionInfoInPlace(PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type)
Definition: tdiconn.c:137
NTSTATUS TdiBuildConnectionInfo(PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Address)
Definition: tdiconn.c:237
PTRANSPORT_ADDRESS TaCopyTransportAddress(PTRANSPORT_ADDRESS OtherAddress)
Definition: tdiconn.c:80
#define NTAPI
Definition: typedefs.h:36
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define FD_ACCEPT_BIT
Definition: winsock2.h:299
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203