ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

listen.c
Go to the documentation of this file.
00001 /* $Id: listen.c 56389 2012-04-22 13:11:54Z tfaber $
00002  * COPYRIGHT:        See COPYING in the top level directory
00003  * PROJECT:          ReactOS kernel
00004  * FILE:             drivers/net/afd/afd/listen.c
00005  * PURPOSE:          Ancillary functions driver
00006  * PROGRAMMER:       Art Yerkes (ayerkes@speakeasy.net)
00007  * UPDATE HISTORY:
00008  * 20040708 Created
00009  */
00010 #include "afd.h"
00011 
00012 static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
00013                                PIRP Irp,
00014                                PFILE_OBJECT NewFileObject,
00015                                PAFD_TDI_OBJECT_QELT Qelt ) {
00016     PAFD_FCB FCB = NewFileObject->FsContext;
00017     NTSTATUS Status;
00018 
00019     if( !SocketAcquireStateLock( FCB ) )
00020         return LostSocket( Irp );
00021 
00022     /* Transfer the connection to the new socket, launch the opening read */
00023     AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %x)\n", FCB));
00024 
00025     FCB->Connection = Qelt->Object;
00026 
00027     if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
00028     FCB->RemoteAddress =
00029         TaCopyTransportAddress( Qelt->ConnInfo->RemoteAddress );
00030 
00031     if( !FCB->RemoteAddress )
00032         Status = STATUS_NO_MEMORY;
00033     else
00034         Status = MakeSocketIntoConnection( FCB );
00035 
00036     if (NT_SUCCESS(Status))
00037         Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, FCB->RemoteAddress);
00038 
00039     if (NT_SUCCESS(Status))
00040         Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, FCB->RemoteAddress);
00041 
00042     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
00043 }
00044 
00045 static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) {
00046     PAFD_RECEIVED_ACCEPT_DATA ListenReceive =
00047         (PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
00048     PTA_IP_ADDRESS IPAddr;
00049 
00050     ListenReceive->SequenceNumber = Qelt->Seq;
00051 
00052     AFD_DbgPrint(MID_TRACE,("Giving SEQ %d to userland\n", Qelt->Seq));
00053     AFD_DbgPrint(MID_TRACE,("Socket Address (K) %x (U) %x\n",
00054                             &ListenReceive->Address,
00055                             Qelt->ConnInfo->RemoteAddress));
00056 
00057     TaCopyTransportAddressInPlace( &ListenReceive->Address,
00058                                    Qelt->ConnInfo->RemoteAddress );
00059 
00060     IPAddr = (PTA_IP_ADDRESS)&ListenReceive->Address;
00061 
00062     AFD_DbgPrint(MID_TRACE,("IPAddr->TAAddressCount %d\n",
00063                             IPAddr->TAAddressCount));
00064     AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressType %d\n",
00065                             IPAddr->Address[0].AddressType));
00066     AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressLength %d\n",
00067                             IPAddr->Address[0].AddressLength));
00068     AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_port %x\n",
00069                             IPAddr->Address[0].Address[0].sin_port));
00070     AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_addr %x\n",
00071                             IPAddr->Address[0].Address[0].in_addr));
00072 
00073     if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
00074 
00075     Irp->IoStatus.Information = ((PCHAR)&IPAddr[1]) - ((PCHAR)ListenReceive);
00076     Irp->IoStatus.Status = STATUS_SUCCESS;
00077     (void)IoSetCancelRoutine(Irp, NULL);
00078     IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
00079     return STATUS_SUCCESS;
00080 }
00081 
00082 static NTSTATUS NTAPI ListenComplete( PDEVICE_OBJECT DeviceObject,
00083                                       PIRP Irp,
00084                                       PVOID Context ) {
00085     NTSTATUS Status = STATUS_SUCCESS;
00086     PAFD_FCB FCB = (PAFD_FCB)Context;
00087     PAFD_TDI_OBJECT_QELT Qelt;
00088     PLIST_ENTRY NextIrpEntry;
00089     PIRP NextIrp;
00090 
00091     if( !SocketAcquireStateLock( FCB ) )
00092         return STATUS_FILE_CLOSED;
00093 
00094     ASSERT(FCB->ListenIrp.InFlightRequest == Irp);
00095     FCB->ListenIrp.InFlightRequest = NULL;
00096 
00097     if( FCB->State == SOCKET_STATE_CLOSED ) {
00098         /* Cleanup our IRP queue because the FCB is being destroyed */
00099         while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) ) {
00100            NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_PREACCEPT]);
00101            NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
00102            NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
00103            NextIrp->IoStatus.Information = 0;
00104            if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
00105            (void)IoSetCancelRoutine(NextIrp, NULL);
00106            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
00107         }
00108 
00109         /* Free ConnectionReturnInfo and ConnectionCallInfo */
00110         if (FCB->ListenIrp.ConnectionReturnInfo)
00111         {
00112             ExFreePool(FCB->ListenIrp.ConnectionReturnInfo);
00113             FCB->ListenIrp.ConnectionReturnInfo = NULL;
00114         }
00115 
00116         if (FCB->ListenIrp.ConnectionCallInfo)
00117         {
00118             ExFreePool(FCB->ListenIrp.ConnectionCallInfo);
00119             FCB->ListenIrp.ConnectionCallInfo = NULL;
00120         }
00121 
00122         SocketStateUnlock( FCB );
00123         return STATUS_FILE_CLOSED;
00124     }
00125 
00126     AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
00127     AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", Irp->IoStatus.Status));
00128 
00129     if (Irp->IoStatus.Status != STATUS_SUCCESS)
00130     {
00131         SocketStateUnlock(FCB);
00132         return Irp->IoStatus.Status;
00133     }
00134 
00135     Qelt = ExAllocatePool( NonPagedPool, sizeof(*Qelt) );
00136     if( !Qelt ) {
00137         Status = STATUS_NO_MEMORY;
00138     } else {
00139         UINT AddressType =
00140             FCB->LocalAddress->Address[0].AddressType;
00141 
00142         Qelt->Object = FCB->Connection;
00143         Qelt->Seq = FCB->ConnSeq++;
00144         AFD_DbgPrint(MID_TRACE,("Address Type: %d (RA %x)\n",
00145                                 AddressType,
00146                                 FCB->ListenIrp.
00147                                 ConnectionReturnInfo->RemoteAddress));
00148 
00149         Status = TdiBuildNullConnectionInfo( &Qelt->ConnInfo, AddressType );
00150         if( NT_SUCCESS(Status) ) {
00151             TaCopyTransportAddressInPlace
00152                ( Qelt->ConnInfo->RemoteAddress,
00153                  FCB->ListenIrp.ConnectionReturnInfo->RemoteAddress );
00154             InsertTailList( &FCB->PendingConnections, &Qelt->ListEntry );
00155         }
00156     }
00157 
00158     /* Satisfy a pre-accept request if one is available */
00159     if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
00160         !IsListEmpty( &FCB->PendingConnections ) ) {
00161         PLIST_ENTRY PendingIrp  =
00162             RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
00163         PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
00164         SatisfyPreAccept
00165             ( CONTAINING_RECORD( PendingIrp, IRP,
00166                                  Tail.Overlay.ListEntry ),
00167               CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT,
00168                                  ListEntry ) );
00169     }
00170 
00171     /* Launch new accept socket */
00172     Status = WarmSocketForConnection( FCB );
00173 
00174     if (NT_SUCCESS(Status))
00175     {
00176         Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionCallInfo,
00177                                                    FCB->LocalAddress->Address[0].AddressType);
00178         ASSERT(Status == STATUS_SUCCESS);
00179 
00180         Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionReturnInfo,
00181                                                    FCB->LocalAddress->Address[0].AddressType);
00182         ASSERT(Status == STATUS_SUCCESS);
00183 
00184         Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
00185                             FCB->Connection.Object,
00186                             &FCB->ListenIrp.ConnectionCallInfo,
00187                             &FCB->ListenIrp.ConnectionReturnInfo,
00188                             &FCB->ListenIrp.Iosb,
00189                             ListenComplete,
00190                             FCB );
00191 
00192         if (Status == STATUS_PENDING)
00193             Status = STATUS_SUCCESS;
00194     }
00195 
00196     /* Trigger a select return if appropriate */
00197     if( !IsListEmpty( &FCB->PendingConnections ) ) {
00198         FCB->PollState |= AFD_EVENT_ACCEPT;
00199         FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
00200         PollReeval( FCB->DeviceExt, FCB->FileObject );
00201     } else
00202         FCB->PollState &= ~AFD_EVENT_ACCEPT;
00203 
00204     SocketStateUnlock( FCB );
00205 
00206     return Status;
00207 }
00208 
00209 NTSTATUS AfdListenSocket( PDEVICE_OBJECT DeviceObject, PIRP Irp,
00210                           PIO_STACK_LOCATION IrpSp ) {
00211     NTSTATUS Status = STATUS_SUCCESS;
00212     PFILE_OBJECT FileObject = IrpSp->FileObject;
00213     PAFD_FCB FCB = FileObject->FsContext;
00214     PAFD_LISTEN_DATA ListenReq;
00215 
00216     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
00217 
00218     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
00219 
00220     if( !(ListenReq = LockRequest( Irp, IrpSp )) )
00221         return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
00222                                        0 );
00223 
00224     if( FCB->State != SOCKET_STATE_BOUND ) {
00225         Status = STATUS_INVALID_PARAMETER;
00226         AFD_DbgPrint(MIN_TRACE,("Could not listen an unbound socket\n"));
00227         return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
00228     }
00229 
00230     FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
00231 
00232     AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
00233 
00234     Status = WarmSocketForConnection( FCB );
00235 
00236     AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status));
00237 
00238     if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
00239 
00240     Status = TdiBuildNullConnectionInfo
00241         ( &FCB->ListenIrp.ConnectionCallInfo,
00242           FCB->LocalAddress->Address[0].AddressType );
00243 
00244     if (!NT_SUCCESS(Status)) return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
00245 
00246     Status = TdiBuildNullConnectionInfo
00247         ( &FCB->ListenIrp.ConnectionReturnInfo,
00248           FCB->LocalAddress->Address[0].AddressType );
00249 
00250     if (!NT_SUCCESS(Status))
00251     {
00252         ExFreePool(FCB->ListenIrp.ConnectionCallInfo);
00253         FCB->ListenIrp.ConnectionCallInfo = NULL;
00254         return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
00255     }
00256 
00257     FCB->State = SOCKET_STATE_LISTENING;
00258 
00259     Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
00260                         FCB->Connection.Object,
00261                         &FCB->ListenIrp.ConnectionCallInfo,
00262                         &FCB->ListenIrp.ConnectionReturnInfo,
00263                         &FCB->ListenIrp.Iosb,
00264                         ListenComplete,
00265                         FCB );
00266 
00267     if( Status == STATUS_PENDING )
00268         Status = STATUS_SUCCESS;
00269 
00270     AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
00271     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
00272 }
00273 
00274 NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp,
00275                            PIO_STACK_LOCATION IrpSp ) {
00276     PFILE_OBJECT FileObject = IrpSp->FileObject;
00277     PAFD_FCB FCB = FileObject->FsContext;
00278     NTSTATUS Status;
00279 
00280     AFD_DbgPrint(MID_TRACE,("Called\n"));
00281 
00282     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
00283 
00284     if( !IsListEmpty( &FCB->PendingConnections ) ) {
00285         PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
00286 
00287         /* We have a pending connection ... complete this irp right away */
00288         Status = SatisfyPreAccept
00289             ( Irp,
00290               CONTAINING_RECORD
00291               ( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) );
00292 
00293         AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
00294 
00295         if ( !IsListEmpty( &FCB->PendingConnections ) )
00296         {
00297              FCB->PollState |= AFD_EVENT_ACCEPT;
00298              FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
00299              PollReeval( FCB->DeviceExt, FCB->FileObject );
00300         } else
00301              FCB->PollState &= ~AFD_EVENT_ACCEPT;
00302 
00303         SocketStateUnlock( FCB );
00304         return Status;
00305     } else if (FCB->NonBlocking) {
00306         AFD_DbgPrint(MIN_TRACE,("No connection ready on a non-blocking socket\n"));
00307 
00308         return UnlockAndMaybeComplete(FCB, STATUS_CANT_WAIT, Irp, 0);
00309     } else {
00310         AFD_DbgPrint(MID_TRACE,("Holding\n"));
00311 
00312         return LeaveIrpUntilLater( FCB, Irp, FUNCTION_PREACCEPT );
00313     }
00314 }
00315 
00316 NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
00317                     PIO_STACK_LOCATION IrpSp ) {
00318     NTSTATUS Status = STATUS_SUCCESS;
00319     PFILE_OBJECT FileObject = IrpSp->FileObject;
00320     PAFD_DEVICE_EXTENSION DeviceExt =
00321         (PAFD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00322     PAFD_FCB FCB = FileObject->FsContext;
00323     PAFD_ACCEPT_DATA AcceptData = Irp->AssociatedIrp.SystemBuffer;
00324     PLIST_ENTRY PendingConn;
00325 
00326     AFD_DbgPrint(MID_TRACE,("Called\n"));
00327 
00328     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
00329 
00330     for( PendingConn = FCB->PendingConnections.Flink;
00331          PendingConn != &FCB->PendingConnections;
00332          PendingConn = PendingConn->Flink ) {
00333         PAFD_TDI_OBJECT_QELT PendingConnObj =
00334             CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry );
00335 
00336         AFD_DbgPrint(MID_TRACE,("Comparing Seq %d to Q %d\n",
00337                                 AcceptData->SequenceNumber,
00338                                 PendingConnObj->Seq));
00339 
00340         if( PendingConnObj->Seq == AcceptData->SequenceNumber ) {
00341             PFILE_OBJECT NewFileObject = NULL;
00342 
00343             RemoveEntryList( PendingConn );
00344 
00345             Status = ObReferenceObjectByHandle
00346                 ( AcceptData->ListenHandle,
00347                   FILE_ALL_ACCESS,
00348                   NULL,
00349                   KernelMode,
00350                   (PVOID *)&NewFileObject,
00351                   NULL );
00352 
00353             if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
00354 
00355             ASSERT(NewFileObject != FileObject);
00356             ASSERT(NewFileObject->FsContext != FCB);
00357 
00358             /* We have a pending connection ... complete this irp right away */
00359             Status = SatisfyAccept( DeviceExt, Irp, NewFileObject, PendingConnObj );
00360 
00361             ObDereferenceObject( NewFileObject );
00362 
00363             AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
00364 
00365             ExFreePool( PendingConnObj );
00366 
00367             FCB->EventSelectDisabled &= ~AFD_EVENT_ACCEPT;
00368 
00369             if( !IsListEmpty( &FCB->PendingConnections ) )
00370             {
00371                 FCB->PollState |= AFD_EVENT_ACCEPT;
00372                 FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
00373                 PollReeval( FCB->DeviceExt, FCB->FileObject );
00374             } else
00375                 FCB->PollState &= ~AFD_EVENT_ACCEPT;
00376 
00377             SocketStateUnlock( FCB );
00378             return Status;
00379         }
00380     }
00381 
00382     AFD_DbgPrint(MIN_TRACE,("No connection waiting\n"));
00383 
00384     return UnlockAndMaybeComplete( FCB, STATUS_UNSUCCESSFUL, Irp, 0 );
00385 }

Generated on Sun May 27 2012 04:28:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.