Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlisten.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
1.7.6.1
|