Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwrite.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: drivers/net/afd/afd/write.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 NTAPI SendComplete 00013 ( PDEVICE_OBJECT DeviceObject, 00014 PIRP Irp, 00015 PVOID Context ) { 00016 NTSTATUS Status = Irp->IoStatus.Status; 00017 PAFD_FCB FCB = (PAFD_FCB)Context; 00018 PLIST_ENTRY NextIrpEntry; 00019 PIRP NextIrp = NULL; 00020 PIO_STACK_LOCATION NextIrpSp; 00021 PAFD_SEND_INFO SendReq = NULL; 00022 PAFD_MAPBUF Map; 00023 UINT TotalBytesCopied = 0, TotalBytesProcessed = 0, SpaceAvail, i; 00024 00025 /* 00026 * The Irp parameter passed in is the IRP of the stream between AFD and 00027 * TDI driver. It's not very usefull to us. We need the IRPs of the stream 00028 * between usermode and AFD. Those are chained from 00029 * FCB->PendingIrpList[FUNCTION_SEND] and you'll see them in the code 00030 * below as "NextIrp" ('cause they are the next usermode IRP to be 00031 * processed). 00032 */ 00033 00034 AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n", 00035 Irp->IoStatus.Status, 00036 Irp->IoStatus.Information)); 00037 00038 if( !SocketAcquireStateLock( FCB ) ) 00039 return STATUS_FILE_CLOSED; 00040 00041 ASSERT(FCB->SendIrp.InFlightRequest == Irp); 00042 FCB->SendIrp.InFlightRequest = NULL; 00043 /* Request is not in flight any longer */ 00044 00045 if( FCB->State == SOCKET_STATE_CLOSED ) { 00046 /* Cleanup our IRP queue because the FCB is being destroyed */ 00047 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { 00048 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); 00049 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 00050 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); 00051 SendReq = GetLockedData(NextIrp, NextIrpSp); 00052 NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; 00053 NextIrp->IoStatus.Information = 0; 00054 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); 00055 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); 00056 (void)IoSetCancelRoutine(NextIrp, NULL); 00057 IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); 00058 } 00059 00060 RetryDisconnectCompletion(FCB); 00061 00062 SocketStateUnlock( FCB ); 00063 return STATUS_FILE_CLOSED; 00064 } 00065 00066 if( !NT_SUCCESS(Status) ) { 00067 /* Complete all following send IRPs with error */ 00068 00069 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { 00070 NextIrpEntry = 00071 RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); 00072 NextIrp = 00073 CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 00074 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); 00075 SendReq = GetLockedData(NextIrp, NextIrpSp); 00076 00077 UnlockBuffers( SendReq->BufferArray, 00078 SendReq->BufferCount, 00079 FALSE ); 00080 00081 NextIrp->IoStatus.Status = Status; 00082 NextIrp->IoStatus.Information = 0; 00083 00084 if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); 00085 (void)IoSetCancelRoutine(NextIrp, NULL); 00086 IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); 00087 } 00088 00089 RetryDisconnectCompletion(FCB); 00090 00091 SocketStateUnlock( FCB ); 00092 00093 return STATUS_SUCCESS; 00094 } 00095 00096 RtlMoveMemory( FCB->Send.Window, 00097 FCB->Send.Window + FCB->Send.BytesUsed, 00098 FCB->Send.BytesUsed - Irp->IoStatus.Information ); 00099 00100 TotalBytesProcessed = 0; 00101 while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && 00102 TotalBytesProcessed != Irp->IoStatus.Information) { 00103 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); 00104 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 00105 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); 00106 SendReq = GetLockedData(NextIrp, NextIrpSp); 00107 Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); 00108 00109 TotalBytesCopied = 0; 00110 00111 for( i = 0; i < SendReq->BufferCount; i++ ) 00112 TotalBytesCopied += SendReq->BufferArray[i].len; 00113 00114 NextIrp->IoStatus.Status = Irp->IoStatus.Status; 00115 NextIrp->IoStatus.Information = TotalBytesCopied; 00116 00117 TotalBytesProcessed += TotalBytesCopied; 00118 00119 (void)IoSetCancelRoutine(NextIrp, NULL); 00120 00121 UnlockBuffers( SendReq->BufferArray, 00122 SendReq->BufferCount, 00123 FALSE ); 00124 00125 if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp); 00126 00127 IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT); 00128 } 00129 00130 ASSERT(TotalBytesProcessed == Irp->IoStatus.Information); 00131 00132 FCB->Send.BytesUsed -= TotalBytesProcessed; 00133 00134 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { 00135 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); 00136 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 00137 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); 00138 SendReq = GetLockedData(NextIrp, NextIrpSp); 00139 Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); 00140 00141 AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq)); 00142 00143 SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; 00144 TotalBytesCopied = 0; 00145 00146 for( i = 0; i < SendReq->BufferCount; i++ ) { 00147 if (SpaceAvail < SendReq->BufferArray[i].len) 00148 { 00149 InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND], 00150 &NextIrp->Tail.Overlay.ListEntry); 00151 NextIrp = NULL; 00152 break; 00153 } 00154 Map[i].BufferAddress = 00155 MmMapLockedPages( Map[i].Mdl, KernelMode ); 00156 00157 RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, 00158 Map[i].BufferAddress, 00159 SendReq->BufferArray[i].len ); 00160 00161 MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl ); 00162 00163 TotalBytesCopied += SendReq->BufferArray[i].len; 00164 SpaceAvail -= SendReq->BufferArray[i].len; 00165 } 00166 00167 if (NextIrp != NULL) 00168 { 00169 FCB->Send.BytesUsed += TotalBytesCopied; 00170 } 00171 else 00172 break; 00173 } 00174 00175 if (FCB->Send.Size - FCB->Send.BytesUsed != 0 && 00176 !FCB->SendClosed) 00177 { 00178 FCB->PollState |= AFD_EVENT_SEND; 00179 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; 00180 PollReeval( FCB->DeviceExt, FCB->FileObject ); 00181 } 00182 else 00183 { 00184 FCB->PollState &= ~AFD_EVENT_SEND; 00185 } 00186 00187 /* Some data is still waiting */ 00188 if( FCB->Send.BytesUsed ) 00189 { 00190 Status = TdiSend( &FCB->SendIrp.InFlightRequest, 00191 FCB->Connection.Object, 00192 0, 00193 FCB->Send.Window, 00194 FCB->Send.BytesUsed, 00195 &FCB->SendIrp.Iosb, 00196 SendComplete, 00197 FCB ); 00198 } 00199 else 00200 { 00201 /* Nothing is waiting so try to complete a pending disconnect */ 00202 RetryDisconnectCompletion(FCB); 00203 } 00204 00205 SocketStateUnlock( FCB ); 00206 00207 return STATUS_SUCCESS; 00208 } 00209 00210 static NTSTATUS NTAPI PacketSocketSendComplete 00211 ( PDEVICE_OBJECT DeviceObject, 00212 PIRP Irp, 00213 PVOID Context ) { 00214 PAFD_FCB FCB = (PAFD_FCB)Context; 00215 PLIST_ENTRY NextIrpEntry; 00216 PIRP NextIrp; 00217 PAFD_SEND_INFO SendReq; 00218 00219 AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n", 00220 Irp->IoStatus.Status, 00221 Irp->IoStatus.Information)); 00222 00223 if( !SocketAcquireStateLock( FCB ) ) 00224 return STATUS_FILE_CLOSED; 00225 00226 ASSERT(FCB->SendIrp.InFlightRequest == Irp); 00227 FCB->SendIrp.InFlightRequest = NULL; 00228 /* Request is not in flight any longer */ 00229 00230 if( FCB->State == SOCKET_STATE_CLOSED ) { 00231 /* Cleanup our IRP queue because the FCB is being destroyed */ 00232 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { 00233 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); 00234 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 00235 SendReq = GetLockedData(NextIrp, IoGetCurrentIrpStackLocation(NextIrp)); 00236 NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; 00237 NextIrp->IoStatus.Information = 0; 00238 (void)IoSetCancelRoutine(NextIrp, NULL); 00239 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); 00240 UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); 00241 IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); 00242 } 00243 SocketStateUnlock( FCB ); 00244 return STATUS_FILE_CLOSED; 00245 } 00246 00247 ASSERT(!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND])); 00248 00249 /* TDI spec guarantees FIFO ordering on IRPs */ 00250 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); 00251 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 00252 00253 SendReq = GetLockedData(NextIrp, IoGetCurrentIrpStackLocation(NextIrp)); 00254 00255 NextIrp->IoStatus.Status = Irp->IoStatus.Status; 00256 NextIrp->IoStatus.Information = Irp->IoStatus.Information; 00257 00258 (void)IoSetCancelRoutine(NextIrp, NULL); 00259 00260 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); 00261 00262 UnlockRequest(NextIrp, IoGetCurrentIrpStackLocation(NextIrp)); 00263 00264 IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT); 00265 00266 FCB->PollState |= AFD_EVENT_SEND; 00267 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; 00268 PollReeval(FCB->DeviceExt, FCB->FileObject); 00269 00270 SocketStateUnlock(FCB); 00271 00272 return STATUS_SUCCESS; 00273 } 00274 00275 NTSTATUS NTAPI 00276 AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00277 PIO_STACK_LOCATION IrpSp, BOOLEAN Short) { 00278 NTSTATUS Status = STATUS_SUCCESS; 00279 PFILE_OBJECT FileObject = IrpSp->FileObject; 00280 PAFD_FCB FCB = FileObject->FsContext; 00281 PAFD_SEND_INFO SendReq; 00282 UINT TotalBytesCopied = 0, i, SpaceAvail = 0; 00283 BOOLEAN NoSpace = FALSE; 00284 00285 AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); 00286 00287 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); 00288 00289 if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) 00290 { 00291 PAFD_SEND_INFO_UDP SendReq; 00292 PTDI_CONNECTION_INFORMATION TargetAddress; 00293 00294 /* Check that the socket is bound */ 00295 if( FCB->State != SOCKET_STATE_BOUND || !FCB->RemoteAddress ) 00296 { 00297 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); 00298 return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 00299 0 ); 00300 } 00301 00302 if( !(SendReq = LockRequest( Irp, IrpSp )) ) 00303 return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); 00304 00305 /* Must lock buffers before handing off user data */ 00306 SendReq->BufferArray = LockBuffers( SendReq->BufferArray, 00307 SendReq->BufferCount, 00308 NULL, NULL, 00309 FALSE, FALSE ); 00310 00311 if( !SendReq->BufferArray ) { 00312 return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, 00313 Irp, 0 ); 00314 } 00315 00316 Status = TdiBuildConnectionInfo( &TargetAddress, FCB->RemoteAddress ); 00317 00318 if( NT_SUCCESS(Status) ) { 00319 FCB->EventSelectDisabled &= ~AFD_EVENT_SEND; 00320 FCB->PollState &= ~AFD_EVENT_SEND; 00321 00322 Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); 00323 if (Status == STATUS_PENDING) 00324 { 00325 TdiSendDatagram(&FCB->SendIrp.InFlightRequest, 00326 FCB->AddressFile.Object, 00327 SendReq->BufferArray[0].buf, 00328 SendReq->BufferArray[0].len, 00329 TargetAddress, 00330 &FCB->SendIrp.Iosb, 00331 PacketSocketSendComplete, 00332 FCB); 00333 } 00334 00335 ExFreePool( TargetAddress ); 00336 00337 SocketStateUnlock(FCB); 00338 00339 return STATUS_PENDING; 00340 } 00341 else 00342 { 00343 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); 00344 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); 00345 } 00346 } 00347 00348 if (FCB->PollState & AFD_EVENT_CLOSE) 00349 { 00350 AFD_DbgPrint(MIN_TRACE,("Connection reset by remote peer\n")); 00351 00352 /* This is an unexpected remote disconnect */ 00353 return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0); 00354 } 00355 00356 if (FCB->PollState & AFD_EVENT_ABORT) 00357 { 00358 AFD_DbgPrint(MIN_TRACE,("Connection aborted\n")); 00359 00360 /* This is an abortive socket closure on our side */ 00361 return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0); 00362 } 00363 00364 if (FCB->SendClosed) 00365 { 00366 AFD_DbgPrint(MIN_TRACE,("No more sends\n")); 00367 00368 /* This is a graceful send closure */ 00369 return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0); 00370 } 00371 00372 if( !(SendReq = LockRequest( Irp, IrpSp )) ) 00373 return UnlockAndMaybeComplete 00374 ( FCB, STATUS_NO_MEMORY, Irp, TotalBytesCopied ); 00375 00376 SendReq->BufferArray = LockBuffers( SendReq->BufferArray, 00377 SendReq->BufferCount, 00378 NULL, NULL, 00379 FALSE, FALSE ); 00380 00381 if( !SendReq->BufferArray ) { 00382 return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, 00383 Irp, 0 ); 00384 } 00385 00386 AFD_DbgPrint(MID_TRACE,("Socket state %d\n", FCB->State)); 00387 00388 if( FCB->State != SOCKET_STATE_CONNECTED ) { 00389 if( (SendReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) ) { 00390 AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); 00391 UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); 00392 return UnlockAndMaybeComplete( FCB, STATUS_CANT_WAIT, Irp, 0 ); 00393 } else { 00394 AFD_DbgPrint(MID_TRACE,("Queuing request\n")); 00395 return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND ); 00396 } 00397 } 00398 00399 AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n", 00400 FCB->Send.BytesUsed)); 00401 00402 SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; 00403 00404 AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n", 00405 SpaceAvail)); 00406 00407 for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size && 00408 i < SendReq->BufferCount; i++ ) { 00409 00410 if (SpaceAvail < SendReq->BufferArray[i].len) 00411 { 00412 if (TotalBytesCopied + SendReq->BufferArray[i].len > FCB->Send.Size) 00413 { 00414 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); 00415 00416 return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_OVERFLOW, Irp, 0); 00417 } 00418 SpaceAvail += TotalBytesCopied; 00419 NoSpace = TRUE; 00420 break; 00421 } 00422 00423 AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n", 00424 i, 00425 SendReq->BufferArray[i].buf, 00426 SendReq->BufferArray[i].len, 00427 FCB->Send.Window + FCB->Send.BytesUsed)); 00428 00429 RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, 00430 SendReq->BufferArray[i].buf, 00431 SendReq->BufferArray[i].len ); 00432 00433 TotalBytesCopied += SendReq->BufferArray[i].len; 00434 SpaceAvail -= SendReq->BufferArray[i].len; 00435 } 00436 00437 FCB->EventSelectDisabled &= ~AFD_EVENT_SEND; 00438 00439 if( TotalBytesCopied == 0 ) { 00440 AFD_DbgPrint(MID_TRACE,("Empty send\n")); 00441 UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); 00442 return UnlockAndMaybeComplete 00443 ( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied ); 00444 } 00445 00446 if (SpaceAvail) 00447 { 00448 FCB->PollState |= AFD_EVENT_SEND; 00449 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; 00450 PollReeval( FCB->DeviceExt, FCB->FileObject ); 00451 } 00452 else 00453 { 00454 FCB->PollState &= ~AFD_EVENT_SEND; 00455 } 00456 00457 if (!NoSpace) 00458 { 00459 FCB->Send.BytesUsed += TotalBytesCopied; 00460 AFD_DbgPrint(MID_TRACE,("Copied %d bytes\n", TotalBytesCopied)); 00461 00462 Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); 00463 if (Status == STATUS_PENDING && !FCB->SendIrp.InFlightRequest) 00464 { 00465 TdiSend(&FCB->SendIrp.InFlightRequest, 00466 FCB->Connection.Object, 00467 0, 00468 FCB->Send.Window, 00469 FCB->Send.BytesUsed, 00470 &FCB->SendIrp.Iosb, 00471 SendComplete, 00472 FCB); 00473 } 00474 SocketStateUnlock(FCB); 00475 00476 return STATUS_PENDING; 00477 } 00478 else 00479 { 00480 FCB->PollState &= ~AFD_EVENT_SEND; 00481 if( (SendReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking) ) { 00482 AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); 00483 UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); 00484 return UnlockAndMaybeComplete( FCB, STATUS_CANT_WAIT, Irp, 0 ); 00485 } else { 00486 AFD_DbgPrint(MID_TRACE,("Queuing request\n")); 00487 return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND ); 00488 } 00489 } 00490 } 00491 00492 NTSTATUS NTAPI 00493 AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00494 PIO_STACK_LOCATION IrpSp) { 00495 NTSTATUS Status = STATUS_SUCCESS; 00496 PTDI_CONNECTION_INFORMATION TargetAddress; 00497 PFILE_OBJECT FileObject = IrpSp->FileObject; 00498 PAFD_FCB FCB = FileObject->FsContext; 00499 PAFD_SEND_INFO_UDP SendReq; 00500 00501 AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); 00502 00503 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); 00504 00505 /* Check that the socket is bound */ 00506 if( FCB->State != SOCKET_STATE_BOUND && 00507 FCB->State != SOCKET_STATE_CREATED) 00508 { 00509 AFD_DbgPrint(MIN_TRACE,("Invalid socket state\n")); 00510 return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); 00511 } 00512 00513 if (FCB->SendClosed) 00514 { 00515 AFD_DbgPrint(MIN_TRACE,("No more sends\n")); 00516 return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0); 00517 } 00518 00519 if( !(SendReq = LockRequest( Irp, IrpSp )) ) 00520 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00521 00522 if (FCB->State == SOCKET_STATE_CREATED) 00523 { 00524 if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress ); 00525 FCB->LocalAddress = 00526 TaBuildNullTransportAddress( ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)-> 00527 Address[0].AddressType ); 00528 00529 if( FCB->LocalAddress ) { 00530 Status = WarmSocketForBind( FCB ); 00531 00532 if( NT_SUCCESS(Status) ) 00533 FCB->State = SOCKET_STATE_BOUND; 00534 else 00535 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); 00536 } else 00537 return UnlockAndMaybeComplete 00538 ( FCB, STATUS_NO_MEMORY, Irp, 0 ); 00539 } 00540 00541 SendReq->BufferArray = LockBuffers( SendReq->BufferArray, 00542 SendReq->BufferCount, 00543 NULL, NULL, 00544 FALSE, FALSE ); 00545 00546 if( !SendReq->BufferArray ) 00547 return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION, 00548 Irp, 0 ); 00549 00550 AFD_DbgPrint 00551 (MID_TRACE,("RemoteAddress #%d Type %d\n", 00552 ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)-> 00553 TAAddressCount, 00554 ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)-> 00555 Address[0].AddressType)); 00556 00557 Status = TdiBuildConnectionInfo( &TargetAddress, 00558 ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress) ); 00559 00560 /* Check the size of the Address given ... */ 00561 00562 if( NT_SUCCESS(Status) ) { 00563 FCB->EventSelectDisabled &= ~AFD_EVENT_SEND; 00564 FCB->PollState &= ~AFD_EVENT_SEND; 00565 00566 Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND); 00567 if (Status == STATUS_PENDING) 00568 { 00569 TdiSendDatagram(&FCB->SendIrp.InFlightRequest, 00570 FCB->AddressFile.Object, 00571 SendReq->BufferArray[0].buf, 00572 SendReq->BufferArray[0].len, 00573 TargetAddress, 00574 &FCB->SendIrp.Iosb, 00575 PacketSocketSendComplete, 00576 FCB); 00577 } 00578 00579 ExFreePool(TargetAddress); 00580 00581 SocketStateUnlock(FCB); 00582 00583 return STATUS_PENDING; 00584 } 00585 else 00586 { 00587 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); 00588 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); 00589 } 00590 } 00591 Generated on Sat May 26 2012 04:16:33 for ReactOS by
1.7.6.1
|