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

write.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 doxygen 1.7.6.1

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