ReactOS 0.4.16-dev-117-g38f21f9
write.c File Reference
#include "afd.h"
Include dependency graph for write.c:

Go to the source code of this file.

Functions

static NTSTATUS NTAPI SendComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
static NTSTATUS NTAPI PacketSocketSendComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS NTAPI AfdConnectedSocketWriteData (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short)
 
NTSTATUS NTAPI AfdPacketSocketWriteData (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 

Variables

static IO_COMPLETION_ROUTINE SendComplete
 
static IO_COMPLETION_ROUTINE PacketSocketSendComplete
 

Function Documentation

◆ AfdConnectedSocketWriteData()

NTSTATUS NTAPI AfdConnectedSocketWriteData ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp,
BOOLEAN  Short 
)

Definition at line 329 of file write.c.

330 {
333 PAFD_FCB FCB = FileObject->FsContext;
334 PAFD_SEND_INFO SendReq;
335 UINT TotalBytesCopied = 0, i, SpaceAvail = 0, BytesCopied, SendLength;
337
340
341 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
342
343 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
344
345 FCB->EventSelectDisabled &= ~AFD_EVENT_SEND;
346
348 {
349 PAFD_SEND_INFO_UDP SendReq;
351
352 /* Check that the socket is bound */
353 if( FCB->State != SOCKET_STATE_BOUND || !FCB->RemoteAddress )
354 {
355 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n"));
357 0 );
358 }
359
360 if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
362
363 /* Must lock buffers before handing off user data */
364 SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
365 SendReq->BufferCount,
366 NULL, NULL,
367 FALSE, FALSE, LockMode );
368
369 if( !SendReq->BufferArray ) {
371 Irp, 0 );
372 }
373
374 Status = TdiBuildConnectionInfo( &TargetAddress, FCB->RemoteAddress );
375
376 if( NT_SUCCESS(Status) ) {
377 FCB->PollState &= ~AFD_EVENT_SEND;
378
380 if (Status == STATUS_PENDING)
381 {
382 Status = TdiSendDatagram(&FCB->SendIrp.InFlightRequest,
383 FCB->AddressFile.Object,
384 SendReq->BufferArray[0].buf,
385 SendReq->BufferArray[0].len,
388 FCB);
389 if (Status != STATUS_PENDING)
390 {
391 NT_VERIFY(RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]) == &Irp->Tail.Overlay.ListEntry);
392 Irp->IoStatus.Status = Status;
393 Irp->IoStatus.Information = 0;
395 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
398 }
399 }
400
402
404
405 return STATUS_PENDING;
406 }
407 else
408 {
409 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
410 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
411 }
412 }
413
414 if (FCB->PollState & AFD_EVENT_CLOSE)
415 {
416 AFD_DbgPrint(MIN_TRACE,("Connection reset by remote peer\n"));
417
418 /* This is an unexpected remote disconnect */
419 return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0);
420 }
421
422 if (FCB->PollState & AFD_EVENT_ABORT)
423 {
424 AFD_DbgPrint(MIN_TRACE,("Connection aborted\n"));
425
426 /* This is an abortive socket closure on our side */
427 return UnlockAndMaybeComplete(FCB, FCB->PollStatus[FD_CLOSE_BIT], Irp, 0);
428 }
429
430 if (FCB->SendClosed)
431 {
432 AFD_DbgPrint(MIN_TRACE,("No more sends\n"));
433
434 /* This is a graceful send closure */
436 }
437
438 if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
440 ( FCB, STATUS_NO_MEMORY, Irp, 0 );
441
442 SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
443 SendReq->BufferCount,
444 NULL, NULL,
445 FALSE, FALSE, LockMode );
446
447 if( !SendReq->BufferArray ) {
449 Irp, 0 );
450 }
451
452 AFD_DbgPrint(MID_TRACE,("Socket state %u\n", FCB->State));
453
454 if( FCB->State != SOCKET_STATE_CONNECTED ) {
455 AFD_DbgPrint(MID_TRACE,("Socket not connected\n"));
456 UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
458 }
459
460 AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %u\n",
461 FCB->Send.BytesUsed));
462
463 SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
464
465 AFD_DbgPrint(MID_TRACE,("We can accept %u bytes\n",
466 SpaceAvail));
467
468 /* Count the total transfer size */
469 SendLength = 0;
470 for (i = 0; i < SendReq->BufferCount; i++)
471 {
472 SendLength += SendReq->BufferArray[i].len;
473 }
474
475 /* Make sure we've got the space */
476 if (SendLength > SpaceAvail)
477 {
478 /* Blocking sockets have to wait here */
479 if (SendLength <= FCB->Send.Size && !((SendReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
480 {
481 FCB->PollState &= ~AFD_EVENT_SEND;
483 }
484
485 /* Check if we can send anything */
486 if (SpaceAvail == 0)
487 {
488 FCB->PollState &= ~AFD_EVENT_SEND;
489
490 /* Non-overlapped sockets will fail if we can send nothing */
491 if (!(SendReq->AfdFlags & AFD_OVERLAPPED))
492 {
493 UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
495 }
496 else
497 {
498 /* Overlapped sockets just pend */
500 }
501 }
502 }
503
504 for ( i = 0; SpaceAvail > 0 && i < SendReq->BufferCount; i++ )
505 {
506 BytesCopied = MIN(SendReq->BufferArray[i].len, SpaceAvail);
507
508 AFD_DbgPrint(MID_TRACE,("Copying Buffer %u, %p:%u to %p\n",
509 i,
510 SendReq->BufferArray[i].buf,
512 FCB->Send.Window + FCB->Send.BytesUsed));
513
514 RtlCopyMemory(FCB->Send.Window + FCB->Send.BytesUsed,
515 SendReq->BufferArray[i].buf,
517
518 TotalBytesCopied += BytesCopied;
519 SpaceAvail -= BytesCopied;
520 FCB->Send.BytesUsed += BytesCopied;
521 }
522
523 Irp->IoStatus.Information = TotalBytesCopied;
524
525 if( TotalBytesCopied == 0 ) {
526 AFD_DbgPrint(MID_TRACE,("Empty send\n"));
527 UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
529 ( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied );
530 }
531
532 if (SpaceAvail)
533 {
534 FCB->PollState |= AFD_EVENT_SEND;
535 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
536 PollReeval( FCB->DeviceExt, FCB->FileObject );
537 }
538 else
539 {
540 FCB->PollState &= ~AFD_EVENT_SEND;
541 }
542
543 /* We use the IRP tail for some temporary storage here */
544 Irp->Tail.Overlay.DriverContext[3] = (PVOID)Irp->IoStatus.Information;
545
547 if (Status == STATUS_PENDING && !FCB->SendIrp.InFlightRequest)
548 {
549 TdiSend(&FCB->SendIrp.InFlightRequest,
550 FCB->Connection.Object,
551 0,
552 FCB->Send.Window,
553 FCB->Send.BytesUsed,
555 FCB);
556 }
557
559
560 return STATUS_PENDING;
561}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define SOCKET_STATE_CONNECTED
Definition: afd.h:76
#define TAG_AFD_TDI_CONNECTION_INFORMATION
Definition: afd.h:53
#define SOCKET_STATE_BOUND
Definition: afd.h:74
#define FUNCTION_SEND
Definition: afd.h:86
LONG NTSTATUS
Definition: precomp.h:26
#define MIN(x, y)
Definition: rdesktop.h:171
#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:33
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
PVOID LockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Output, KPROCESSOR_MODE *LockMode)
Definition: lock.c:24
VOID UnlockBuffers(PAFD_WSABUF Buf, UINT Count, BOOL Address)
Definition: lock.c:289
VOID UnlockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:180
NTSTATUS QueueUserModeIrp(PAFD_FCB FCB, PIRP Irp, UINT Function)
Definition: lock.c:397
NTSTATUS LostSocket(PIRP Irp)
Definition: lock.c:387
NTSTATUS NTAPI UnlockAndMaybeComplete(PAFD_FCB FCB, NTSTATUS Status, PIRP Irp, UINT Information)
Definition: lock.c:375
PAFD_WSABUF LockBuffers(PAFD_WSABUF Buf, UINT Count, PVOID AddressBuf, PINT AddressLen, BOOLEAN Write, BOOLEAN LockAddress, KPROCESSOR_MODE LockMode)
Definition: lock.c:205
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 TdiSendDatagram(PIRP *Irp, PFILE_OBJECT TransportObject, PCHAR Buffer, UINT BufferLength, PTDI_CONNECTION_INFORMATION Addr, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Definition: tdi.c:1151
NTSTATUS TdiSend(PIRP *Irp, PFILE_OBJECT TransportObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Definition: tdi.c:898
static IO_COMPLETION_ROUTINE SendComplete
Definition: write.c:13
static IO_COMPLETION_ROUTINE PacketSocketSendComplete
Definition: write.c:260
#define AFD_DbgPrint(_t_, _x_)
Definition: debug.h:60
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
ULONG LockMode
Definition: env_spec_w32.cpp:8
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
short Short
Definition: ftraster.c:311
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
IoSetCancelRoutine(Irp, CancelRoutine)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned int UINT
Definition: ndis.h:50
_In_ UINT _In_ UINT _In_ PNDIS_PACKET _In_ UINT _Out_ PUINT BytesCopied
Definition: ndis.h:3171
#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_INVALID_CONNECTION
Definition: ntstatus.h:556
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define AFD_IMMEDIATE
Definition: shared.h:220
#define AFD_EVENT_SEND
Definition: shared.h:205
#define AFD_OVERLAPPED
Definition: shared.h:219
#define AFD_EVENT_ABORT
Definition: shared.h:207
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:153
#define AFD_EVENT_CLOSE
Definition: shared.h:208
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: afd.h:159
ULONG BufferCount
Definition: shared.h:109
PAFD_WSABUF BufferArray
Definition: shared.h:108
PCHAR buf
Definition: shared.h:18
UINT len
Definition: shared.h:17
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
NTSTATUS TdiBuildConnectionInfo(PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Address)
Definition: tdiconn.c:237
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define FD_CLOSE_BIT
Definition: winsock2.h:303
#define FD_WRITE_BIT
Definition: winsock2.h:295
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER _Outptr_ PVOID * TargetAddress
Definition: iotypes.h:1037
* PFILE_OBJECT
Definition: iotypes.h:1998
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3301

Referenced by AfdDispatch(), and StreamSocketConnectComplete().

◆ AfdPacketSocketWriteData()

NTSTATUS NTAPI AfdPacketSocketWriteData ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 564 of file write.c.

565 {
569 PAFD_FCB FCB = FileObject->FsContext;
570 PAFD_SEND_INFO_UDP SendReq;
572
574
575 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
576
577 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
578
579 FCB->EventSelectDisabled &= ~AFD_EVENT_SEND;
580
581 /* Check that the socket is bound */
582 if( FCB->State != SOCKET_STATE_BOUND &&
583 FCB->State != SOCKET_STATE_CREATED)
584 {
585 AFD_DbgPrint(MIN_TRACE,("Invalid socket state\n"));
587 }
588
589 if (FCB->SendClosed)
590 {
591 AFD_DbgPrint(MIN_TRACE,("No more sends\n"));
593 }
594
595 if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
597
598 if (FCB->State == SOCKET_STATE_CREATED)
599 {
600 if (FCB->LocalAddress)
601 {
603 }
604
605 FCB->LocalAddress =
607 Address[0].AddressType );
608
609 if( FCB->LocalAddress ) {
611
612 if( NT_SUCCESS(Status) )
613 FCB->State = SOCKET_STATE_BOUND;
614 else
615 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
616 } else
618 ( FCB, STATUS_NO_MEMORY, Irp, 0 );
619 }
620
621 SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
622 SendReq->BufferCount,
623 NULL, NULL,
624 FALSE, FALSE, LockMode );
625
626 if( !SendReq->BufferArray )
628 Irp, 0 );
629
631 (MID_TRACE,("RemoteAddress #%d Type %u\n",
633 TAAddressCount,
635 Address[0].AddressType));
636
639
640 /* Check the size of the Address given ... */
641
642 if( NT_SUCCESS(Status) ) {
643 FCB->PollState &= ~AFD_EVENT_SEND;
644
646 if (Status == STATUS_PENDING)
647 {
648 Status = TdiSendDatagram(&FCB->SendIrp.InFlightRequest,
649 FCB->AddressFile.Object,
650 SendReq->BufferArray[0].buf,
651 SendReq->BufferArray[0].len,
654 FCB);
655 if (Status != STATUS_PENDING)
656 {
657 NT_VERIFY(RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]) == &Irp->Tail.Overlay.ListEntry);
658 Irp->IoStatus.Status = Status;
659 Irp->IoStatus.Information = 0;
661 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
664 }
665 }
666
668
670
671 return STATUS_PENDING;
672 }
673 else
674 {
675 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
676 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
677 }
678}
#define SOCKET_STATE_CREATED
Definition: afd.h:73
#define TAG_AFD_TRANSPORT_ADDRESS
Definition: afd.h:39
NTSTATUS WarmSocketForBind(PAFD_FCB FCB, ULONG ShareType)
Definition: bind.c:13
static WCHAR Address[46]
Definition: ping.c:68
#define AFD_SHARE_WILDCARD
Definition: shared.h:193
TDI_CONNECTION_INFORMATION TdiConnection
Definition: shared.h:112
PTRANSPORT_ADDRESS TaBuildNullTransportAddress(UINT AddressType)
Definition: tdiconn.c:113

Referenced by AfdDispatch().

◆ PacketSocketSendComplete()

static NTSTATUS NTAPI PacketSocketSendComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)
static

Definition at line 261 of file write.c.

264 {
266 PLIST_ENTRY NextIrpEntry;
267 PIRP NextIrp;
268 PAFD_SEND_INFO SendReq;
269
271
272 AFD_DbgPrint(MID_TRACE,("Called, status %x, %u bytes used\n",
273 Irp->IoStatus.Status,
274 Irp->IoStatus.Information));
275
277 return STATUS_FILE_CLOSED;
278
279 ASSERT(FCB->SendIrp.InFlightRequest == Irp);
280 FCB->SendIrp.InFlightRequest = NULL;
281 /* Request is not in flight any longer */
282
283 if( FCB->State == SOCKET_STATE_CLOSED ) {
284 /* Cleanup our IRP queue because the FCB is being destroyed */
285 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
286 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
287 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
288 SendReq = GetLockedData(NextIrp, IoGetCurrentIrpStackLocation(NextIrp));
290 NextIrp->IoStatus.Information = 0;
291 (void)IoSetCancelRoutine(NextIrp, NULL);
292 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
293 UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
295 }
297 return STATUS_FILE_CLOSED;
298 }
299
300 ASSERT(!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]));
301
302 /* TDI spec guarantees FIFO ordering on IRPs */
303 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
304 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
305
306 SendReq = GetLockedData(NextIrp, IoGetCurrentIrpStackLocation(NextIrp));
307
308 NextIrp->IoStatus.Status = Irp->IoStatus.Status;
309 NextIrp->IoStatus.Information = Irp->IoStatus.Information;
310
311 (void)IoSetCancelRoutine(NextIrp, NULL);
312
313 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
314
316
318
319 FCB->PollState |= AFD_EVENT_SEND;
320 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
321 PollReeval(FCB->DeviceExt, FCB->FileObject);
322
324
325 return STATUS_SUCCESS;
326}
#define SOCKET_STATE_CLOSED
Definition: afd.h:82
struct _AFD_FCB * PAFD_FCB
PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:13
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ASSERT(a)
Definition: mode.c:44
ULONG BufferCount
Definition: shared.h:102
PAFD_WSABUF BufferArray
Definition: shared.h:101
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ SendComplete()

static NTSTATUS NTAPI SendComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)
static

Definition at line 14 of file write.c.

17 {
18 NTSTATUS Status = Irp->IoStatus.Status;
20 PLIST_ENTRY NextIrpEntry;
21 PIRP NextIrp = NULL;
22 PIO_STACK_LOCATION NextIrpSp;
23 PAFD_SEND_INFO SendReq = NULL;
24 PAFD_MAPBUF Map;
25 SIZE_T TotalBytesCopied = 0, TotalBytesProcessed = 0, SpaceAvail, i;
26 UINT SendLength, BytesCopied;
27 BOOLEAN HaltSendQueue;
28
30
31 /*
32 * The Irp parameter passed in is the IRP of the stream between AFD and
33 * TDI driver. It's not very useful to us. We need the IRPs of the stream
34 * between usermode and AFD. Those are chained from
35 * FCB->PendingIrpList[FUNCTION_SEND] and you'll see them in the code
36 * below as "NextIrp" ('cause they are the next usermode IRP to be
37 * processed).
38 */
39
40 AFD_DbgPrint(MID_TRACE,("Called, status %x, %u bytes used\n",
41 Irp->IoStatus.Status,
42 Irp->IoStatus.Information));
43
45 return STATUS_FILE_CLOSED;
46
47 ASSERT(FCB->SendIrp.InFlightRequest == Irp);
48 FCB->SendIrp.InFlightRequest = NULL;
49 /* Request is not in flight any longer */
50
51 if( FCB->State == SOCKET_STATE_CLOSED ) {
52 /* Cleanup our IRP queue because the FCB is being destroyed */
53 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
54 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
55 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
56 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
57 SendReq = GetLockedData(NextIrp, NextIrpSp);
59 NextIrp->IoStatus.Information = 0;
60 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
61 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
62 (void)IoSetCancelRoutine(NextIrp, NULL);
64 }
65
67
69 return STATUS_FILE_CLOSED;
70 }
71
72 if( !NT_SUCCESS(Status) ) {
73 /* Complete all following send IRPs with error */
74
75 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
76 NextIrpEntry =
77 RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
78 NextIrp =
79 CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
80 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
81 SendReq = GetLockedData(NextIrp, NextIrpSp);
82
83 UnlockBuffers( SendReq->BufferArray,
84 SendReq->BufferCount,
85 FALSE );
86
87 NextIrp->IoStatus.Status = Status;
88 NextIrp->IoStatus.Information = 0;
89
90 if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
91 (void)IoSetCancelRoutine(NextIrp, NULL);
93 }
94
96
98
99 return STATUS_SUCCESS;
100 }
101
102 RtlMoveMemory( FCB->Send.Window,
103 FCB->Send.Window + Irp->IoStatus.Information,
104 FCB->Send.BytesUsed - Irp->IoStatus.Information );
105
106 TotalBytesProcessed = 0;
107 SendLength = Irp->IoStatus.Information;
108 HaltSendQueue = FALSE;
109 while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && SendLength > 0) {
110 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
111 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
112 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
113 SendReq = GetLockedData(NextIrp, NextIrpSp);
114 Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
115
116 TotalBytesCopied = (ULONG_PTR)NextIrp->Tail.Overlay.DriverContext[3];
117 ASSERT(TotalBytesCopied != 0);
118
119 /* If we didn't get enough, keep waiting */
120 if (TotalBytesCopied > SendLength)
121 {
122 /* Update the bytes left to copy */
123 TotalBytesCopied -= SendLength;
124 NextIrp->Tail.Overlay.DriverContext[3] = (PVOID)TotalBytesCopied;
125
126 /* Update the state variables */
127 FCB->Send.BytesUsed -= SendLength;
128 TotalBytesProcessed += SendLength;
129 SendLength = 0;
130
131 /* Pend the IRP */
132 InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND],
133 &NextIrp->Tail.Overlay.ListEntry);
134 HaltSendQueue = TRUE;
135 break;
136 }
137
138 ASSERT(NextIrp->IoStatus.Information != 0);
139
140 NextIrp->IoStatus.Status = Irp->IoStatus.Status;
141
142 FCB->Send.BytesUsed -= TotalBytesCopied;
143 TotalBytesProcessed += TotalBytesCopied;
144 SendLength -= TotalBytesCopied;
145
146 (void)IoSetCancelRoutine(NextIrp, NULL);
147
148 UnlockBuffers( SendReq->BufferArray,
149 SendReq->BufferCount,
150 FALSE );
151
152 if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp);
153
155 }
156
157 ASSERT(SendLength == 0);
158
159 if ( !HaltSendQueue && !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
160 NextIrpEntry = FCB->PendingIrpList[FUNCTION_SEND].Flink;
161 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
162 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
163 SendReq = GetLockedData(NextIrp, NextIrpSp);
164 Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
165
166 AFD_DbgPrint(MID_TRACE,("SendReq @ %p\n", SendReq));
167
168 SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
169 TotalBytesCopied = 0;
170
171 /* Count the total transfer size */
172 SendLength = 0;
173 for (i = 0; i < SendReq->BufferCount; i++)
174 {
175 SendLength += SendReq->BufferArray[i].len;
176 }
177
178 /* Make sure we've got the space */
179 if (SendLength > SpaceAvail)
180 {
181 /* Blocking sockets have to wait here */
182 if (SendLength <= FCB->Send.Size && !((SendReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
183 {
184 FCB->PollState &= ~AFD_EVENT_SEND;
185
186 NextIrp = NULL;
187 }
188
189 /* Check if we can send anything */
190 if (SpaceAvail == 0)
191 {
192 FCB->PollState &= ~AFD_EVENT_SEND;
193
194 /* We should never be non-overlapped and get to this point */
195 ASSERT(SendReq->AfdFlags & AFD_OVERLAPPED);
196
197 NextIrp = NULL;
198 }
199 }
200
201 if (NextIrp != NULL)
202 {
203 for( i = 0; i < SendReq->BufferCount; i++ ) {
204 BytesCopied = MIN(SendReq->BufferArray[i].len, SpaceAvail);
205
206 Map[i].BufferAddress =
208
209 RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
210 Map[i].BufferAddress,
211 BytesCopied );
212
213 MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
214
215 TotalBytesCopied += BytesCopied;
216 SpaceAvail -= BytesCopied;
217 FCB->Send.BytesUsed += BytesCopied;
218 }
219
220 NextIrp->IoStatus.Information = TotalBytesCopied;
221 NextIrp->Tail.Overlay.DriverContext[3] = (PVOID)NextIrp->IoStatus.Information;
222 }
223 }
224
225 if (FCB->Send.Size - FCB->Send.BytesUsed != 0 && !FCB->SendClosed &&
226 IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]))
227 {
228 FCB->PollState |= AFD_EVENT_SEND;
229 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
230 PollReeval( FCB->DeviceExt, FCB->FileObject );
231 }
232 else
233 {
234 FCB->PollState &= ~AFD_EVENT_SEND;
235 }
236
237
238 /* Some data is still waiting */
239 if( FCB->Send.BytesUsed )
240 {
241 Status = TdiSend( &FCB->SendIrp.InFlightRequest,
242 FCB->Connection.Object,
243 0,
244 FCB->Send.Window,
245 FCB->Send.BytesUsed,
247 FCB );
248 }
249 else
250 {
251 /* Nothing is waiting so try to complete a pending disconnect */
253 }
254
256
257 return STATUS_SUCCESS;
258}
unsigned char BOOLEAN
struct _AFD_MAPBUF * PAFD_MAPBUF
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:990
#define TRUE
Definition: types.h:120
VOID RetryDisconnectCompletion(PAFD_FCB FCB)
Definition: main.c:703
#define ULONG_PTR
Definition: config.h:101
#define InsertHeadList(ListHead, Entry)
PVOID NTAPI MmMapLockedPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode)
Definition: mdlsup.c:818
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
#define KernelMode
Definition: asm.h:34
PVOID BufferAddress
Definition: afd.h:104
ULONG AfdFlags
Definition: shared.h:103
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl

Variable Documentation

◆ PacketSocketSendComplete

IO_COMPLETION_ROUTINE PacketSocketSendComplete
static

Definition at line 260 of file write.c.

Referenced by AfdConnectedSocketWriteData(), and AfdPacketSocketWriteData().

◆ SendComplete

IO_COMPLETION_ROUTINE SendComplete
static

Definition at line 13 of file write.c.

Referenced by AfdConnectedSocketWriteData(), DECLARE_INTERFACE_(), and SendComplete().