ReactOS 0.4.15-dev-7942-gd23573b
read.c File Reference
#include "afd.h"
Include dependency graph for read.c:

Go to the source code of this file.

Functions

static VOID RefillSocketBuffer (PAFD_FCB FCB)
 
static VOID HandleReceiveComplete (PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information)
 
static BOOLEAN CantReadMore (PAFD_FCB FCB)
 
static NTSTATUS TryToSatisfyRecvRequestFromBuffer (PAFD_FCB FCB, PAFD_RECV_INFO RecvReq, PUINT TotalBytesCopied)
 
static NTSTATUS ReceiveActivity (PAFD_FCB FCB, PIRP Irp)
 
NTSTATUS NTAPI ReceiveComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
static NTSTATUS NTAPI SatisfyPacketRecvRequest (PAFD_FCB FCB, PIRP Irp, PAFD_STORED_DATAGRAM DatagramRecv, PUINT TotalBytesCopied)
 
NTSTATUS NTAPI AfdConnectedSocketReadData (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short)
 
NTSTATUS NTAPI PacketSocketRecvComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS NTAPI AfdPacketSocketReadData (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 

Function Documentation

◆ AfdConnectedSocketReadData()

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

Definition at line 415 of file read.c.

416 {
419 PAFD_FCB FCB = FileObject->FsContext;
420 PAFD_RECV_INFO RecvReq;
421 UINT TotalBytesCopied = 0;
422 PAFD_STORED_DATAGRAM DatagramRecv;
423 PLIST_ENTRY ListEntry;
425
428
429 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
430
431 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
432
433 FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
434
436 FCB->State != SOCKET_STATE_CONNECTED &&
437 FCB->State != SOCKET_STATE_CONNECTING ) {
438 AFD_DbgPrint(MIN_TRACE,("Called recv on wrong kind of socket (s%x)\n",
439 FCB->State));
441 Irp, 0 );
442 }
443
444 if( !(RecvReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
446 Irp, 0 );
447
448 AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
449
450 RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
451 RecvReq->BufferCount,
452 NULL, NULL,
453 TRUE, FALSE, LockMode );
454
455 if( !RecvReq->BufferArray ) {
457 Irp, 0 );
458 }
459
461 {
462 if (!IsListEmpty(&FCB->DatagramList))
463 {
464 ListEntry = RemoveHeadList(&FCB->DatagramList);
465 DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
466 Status = SatisfyPacketRecvRequest(FCB, Irp, DatagramRecv,
467 (PUINT)&Irp->IoStatus.Information);
468
469 if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
470 {
471 InsertHeadList(&FCB->DatagramList,
472 &DatagramRecv->ListEntry);
473 }
474
475 if (!IsListEmpty(&FCB->DatagramList))
476 {
477 FCB->PollState |= AFD_EVENT_RECEIVE;
478 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
479 PollReeval( FCB->DeviceExt, FCB->FileObject );
480 }
481 else
482 FCB->PollState &= ~AFD_EVENT_RECEIVE;
483
484 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
485
486 return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
487 }
488 else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) &&
489 ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
490 {
491 AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
493 FCB->PollState &= ~AFD_EVENT_RECEIVE;
494 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
495 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
496 }
497 else
498 {
499 FCB->PollState &= ~AFD_EVENT_RECEIVE;
501 }
502 }
503
504 Irp->IoStatus.Status = STATUS_PENDING;
505 Irp->IoStatus.Information = 0;
506
507 InsertTailList( &FCB->PendingIrpList[FUNCTION_RECV],
508 &Irp->Tail.Overlay.ListEntry );
509
510 /************ From this point, the IRP is not ours ************/
511
513
514 if( Status == STATUS_PENDING &&
515 !(RecvReq->AfdFlags & AFD_OVERLAPPED) &&
516 ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking))) {
517 AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
519 TotalBytesCopied = 0;
520 RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
521 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
523 TotalBytesCopied );
524 } else if( Status == STATUS_PENDING ) {
525 AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
528 } else {
529 AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
530 }
531
533 return Status;
534}
#define SOCKET_STATE_CONNECTED
Definition: afd.h:76
#define FUNCTION_RECV
Definition: afd.h:85
DRIVER_CANCEL AfdCancelHandler
Definition: afd.h:302
#define SOCKET_STATE_CONNECTING
Definition: afd.h:75
LONG NTSTATUS
Definition: precomp.h:26
#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 TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_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
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
#define AFD_DbgPrint(_t_, _x_)
Definition: debug.h:60
ULONG LockMode
Definition: env_spec_w32.cpp:8
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
short Short
Definition: ftraster.c:311
Status
Definition: gdiplustypes.h:25
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
static NTSTATUS NTAPI SatisfyPacketRecvRequest(PAFD_FCB FCB, PIRP Irp, PAFD_STORED_DATAGRAM DatagramRecv, PUINT TotalBytesCopied)
Definition: read.c:314
static NTSTATUS ReceiveActivity(PAFD_FCB FCB, PIRP Irp)
Definition: read.c:151
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#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_OVERLAPPED
Definition: shared.h:219
#define AFD_EVENT_RECEIVE
Definition: shared.h:203
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:153
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: afd.h:159
ULONG BufferCount
Definition: shared.h:86
ULONG TdiFlags
Definition: shared.h:88
ULONG AfdFlags
Definition: shared.h:87
PAFD_WSABUF BufferArray
Definition: shared.h:85
LIST_ENTRY ListEntry
Definition: afd.h:153
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
Definition: typedefs.h:120
#define TDI_RECEIVE_PEEK
Definition: tdi.h:124
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#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_READ_BIT
Definition: winsock2.h:293
* PFILE_OBJECT
Definition: iotypes.h:1998
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7

Referenced by AfdDispatch().

◆ AfdPacketSocketReadData()

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

Definition at line 696 of file read.c.

697 {
700 PAFD_FCB FCB = FileObject->FsContext;
701 PAFD_RECV_INFO_UDP RecvReq;
702 PLIST_ENTRY ListEntry;
703 PAFD_STORED_DATAGRAM DatagramRecv;
705
707
708 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
709
710 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
711
712 FCB->EventSelectDisabled &= ~AFD_EVENT_RECEIVE;
713
714 /* Check that the socket is bound */
715 if( FCB->State != SOCKET_STATE_BOUND )
716 {
717 AFD_DbgPrint(MIN_TRACE,("Invalid socket state\n"));
719 }
720
721 if (FCB->TdiReceiveClosed)
722 {
723 AFD_DbgPrint(MIN_TRACE,("Receive closed\n"));
725 }
726
727 if( !(RecvReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
729
730 AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
731
732 RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
733 RecvReq->BufferCount,
734 RecvReq->Address,
735 RecvReq->AddressLength,
736 TRUE, TRUE, LockMode );
737
738 if( !RecvReq->BufferArray ) { /* access violation in userspace */
740 }
741
742 if (!IsListEmpty(&FCB->DatagramList))
743 {
744 ListEntry = RemoveHeadList(&FCB->DatagramList);
745 DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
746 Status = SatisfyPacketRecvRequest(FCB, Irp, DatagramRecv,
747 (PUINT)&Irp->IoStatus.Information);
748
749 if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
750 {
751 InsertHeadList(&FCB->DatagramList,
752 &DatagramRecv->ListEntry);
753 }
754
755 if (!IsListEmpty(&FCB->DatagramList))
756 {
757 FCB->PollState |= AFD_EVENT_RECEIVE;
758 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
759 PollReeval( FCB->DeviceExt, FCB->FileObject );
760 }
761 else
762 FCB->PollState &= ~AFD_EVENT_RECEIVE;
763
764 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, TRUE);
765
766 return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
767 }
768 else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) &&
769 ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking)))
770 {
771 AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
773 FCB->PollState &= ~AFD_EVENT_RECEIVE;
774 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
775 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
776 }
777 else
778 {
779 FCB->PollState &= ~AFD_EVENT_RECEIVE;
781 }
782}
#define SOCKET_STATE_BOUND
Definition: afd.h:74
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
ULONG AfdFlags
Definition: shared.h:94
PINT AddressLength
Definition: shared.h:97
ULONG BufferCount
Definition: shared.h:93
ULONG TdiFlags
Definition: shared.h:95
PAFD_WSABUF BufferArray
Definition: shared.h:92

Referenced by AfdDispatch().

◆ CantReadMore()

static BOOLEAN CantReadMore ( PAFD_FCB  FCB)
static

Definition at line 88 of file read.c.

88 {
89 UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
90
91 return !BytesAvailable && FCB->TdiReceiveClosed;
92}

Referenced by ReceiveActivity(), and TryToSatisfyRecvRequestFromBuffer().

◆ HandleReceiveComplete()

static VOID HandleReceiveComplete ( PAFD_FCB  FCB,
NTSTATUS  Status,
ULONG_PTR  Information 
)
static

Definition at line 53 of file read.c.

54{
55 FCB->LastReceiveStatus = Status;
56
57 /* We got closed while the receive was in progress */
58 if (FCB->TdiReceiveClosed)
59 {
60 /* The received data is discarded */
61 }
62 /* Receive successful */
63 else if (Status == STATUS_SUCCESS)
64 {
65 FCB->Recv.Content += Information;
66 ASSERT(FCB->Recv.Content <= FCB->Recv.Size);
67
68 /* Check for graceful closure */
69 if (Information == 0)
70 {
71 /* Receive is closed */
72 FCB->TdiReceiveClosed = TRUE;
73 }
74 else
75 {
76 /* Issue another receive IRP to keep the buffer well stocked */
78 }
79 }
80 /* Receive failed with no data (unexpected closure) */
81 else
82 {
83 /* Previously received data remains intact */
84 FCB->TdiReceiveClosed = TRUE;
85 }
86}
#define ASSERT(a)
Definition: mode.c:44
static VOID RefillSocketBuffer(PAFD_FCB FCB)
Definition: read.c:13
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049

Referenced by ReceiveComplete().

◆ PacketSocketRecvComplete()

NTSTATUS NTAPI PacketSocketRecvComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 537 of file read.c.

540 {
543 PIRP NextIrp;
544 PIO_STACK_LOCATION NextIrpSp;
545 PLIST_ENTRY ListEntry;
546 PAFD_RECV_INFO RecvReq;
547 PAFD_STORED_DATAGRAM DatagramRecv;
548 UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM );
549 PLIST_ENTRY NextIrpEntry, DatagramRecvEntry;
550
552
553 AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));
554
556 return STATUS_FILE_CLOSED;
557
558 ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
559 FCB->ReceiveIrp.InFlightRequest = NULL;
560
561 if( FCB->State == SOCKET_STATE_CLOSED ) {
562 /* Cleanup our IRP queue because the FCB is being destroyed */
563 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
564 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
565 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
566 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
567 RecvReq = GetLockedData(NextIrp, NextIrpSp);
569 NextIrp->IoStatus.Information = 0;
570 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp));
571 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
572 (void)IoSetCancelRoutine(NextIrp, NULL);
574 }
575
576 /* Free all items on the datagram list */
577 while( !IsListEmpty( &FCB->DatagramList ) ) {
578 DatagramRecvEntry = RemoveHeadList(&FCB->DatagramList);
579 DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry);
582 }
583
585 return STATUS_FILE_CLOSED;
586 }
587
588 if (Irp->IoStatus.Status != STATUS_SUCCESS)
589 {
591 return Irp->IoStatus.Status;
592 }
593
594 if (FCB->TdiReceiveClosed)
595 {
597 return STATUS_FILE_CLOSED;
598 }
599
600 DatagramRecv = ExAllocatePoolWithTag(NonPagedPool,
601 DGSize,
603
604 if( DatagramRecv ) {
605 DatagramRecv->Len = Irp->IoStatus.Information;
606 RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
607 DatagramRecv->Len );
608 AFD_DbgPrint(MID_TRACE,("Received (A %p)\n",
609 FCB->AddressFrom->RemoteAddress));
610 DatagramRecv->Address =
611 TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );
612
613 if( !DatagramRecv->Address ) Status = STATUS_NO_MEMORY;
614
615 } else Status = STATUS_NO_MEMORY;
616
617 if( !NT_SUCCESS( Status ) ) {
618
619 if (DatagramRecv)
620 {
622 }
623
625 return Status;
626 } else {
627 FCB->Recv.Content += DatagramRecv->Len;
628 InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
629 }
630
631 /* Satisfy as many requests as we can */
632
633 while( !IsListEmpty( &FCB->DatagramList ) &&
634 !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
635 AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
636 ListEntry = RemoveHeadList( &FCB->DatagramList );
637 DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
638 ListEntry );
639 ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
640 NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
641 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
642 RecvReq = GetLockedData(NextIrp, NextIrpSp);
643
644 AFD_DbgPrint(MID_TRACE,("RecvReq: %p, DatagramRecv: %p\n",
645 RecvReq, DatagramRecv));
646
647 AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
649 ( FCB, NextIrp, DatagramRecv,
650 (PUINT)&NextIrp->IoStatus.Information );
651
652 if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
653 {
654 InsertHeadList(&FCB->DatagramList,
655 &DatagramRecv->ListEntry);
656 }
657
658 AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
659 UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
660 if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
661
662 AFD_DbgPrint(MID_TRACE,("Completing\n"));
663 (void)IoSetCancelRoutine(NextIrp, NULL);
664 NextIrp->IoStatus.Status = Status;
665
667 }
668
669 if( !IsListEmpty( &FCB->DatagramList ) && IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
670 AFD_DbgPrint(MID_TRACE,("Signalling\n"));
671 FCB->PollState |= AFD_EVENT_RECEIVE;
672 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
673 PollReeval( FCB->DeviceExt, FCB->FileObject );
674 } else
675 FCB->PollState &= ~AFD_EVENT_RECEIVE;
676
677 if( NT_SUCCESS(Irp->IoStatus.Status) && FCB->Recv.Content < FCB->Recv.Size ) {
678 /* Now relaunch the datagram request */
680 ( &FCB->ReceiveIrp.InFlightRequest,
681 FCB->AddressFile.Object,
682 0,
683 FCB->Recv.Window,
684 FCB->Recv.Size,
685 FCB->AddressFrom,
687 FCB );
688 }
689
691
692 return STATUS_SUCCESS;
693}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define SOCKET_STATE_CLOSED
Definition: afd.h:82
#define TAG_AFD_STORED_DATAGRAM
Definition: afd.h:51
IO_COMPLETION_ROUTINE PacketSocketRecvComplete
Definition: afd.h:310
struct _AFD_STORED_DATAGRAM AFD_STORED_DATAGRAM
#define TAG_AFD_TRANSPORT_ADDRESS
Definition: afd.h:39
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID UnlockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:180
PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:13
BOOLEAN CheckUnlockExtraBuffers(PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp)
Definition: main.c:1089
NTSTATUS TdiReceiveDatagram(PIRP *Irp, PFILE_OBJECT TransportObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PTDI_CONNECTION_INFORMATION Addr, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Definition: tdi.c:1058
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IoCompleteRequest
Definition: irp.c:1240
PTRANSPORT_ADDRESS Address
Definition: afd.h:155
CHAR Buffer[1]
Definition: afd.h:156
IO_STATUS_BLOCK IoStatus
PTRANSPORT_ADDRESS TaCopyTransportAddress(PTRANSPORT_ADDRESS OtherAddress)
Definition: tdiconn.c:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

◆ ReceiveActivity()

static NTSTATUS ReceiveActivity ( PAFD_FCB  FCB,
PIRP  Irp 
)
static

Definition at line 151 of file read.c.

151 {
152 PLIST_ENTRY NextIrpEntry;
153 PIRP NextIrp;
154 PIO_STACK_LOCATION NextIrpSp;
155 PAFD_RECV_INFO RecvReq;
156 UINT TotalBytesCopied = 0;
158
159 AFD_DbgPrint(MID_TRACE,("%p %p\n", FCB, Irp));
160
161 AFD_DbgPrint(MID_TRACE,("FCB %p Receive data waiting %u\n",
162 FCB, FCB->Recv.Content));
163
164 if( CantReadMore( FCB ) ) {
165 /* Success here means that we got an EOF. Complete a pending read
166 * with zero bytes if we haven't yet overread, then kill the others.
167 */
168 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
169 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
170 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
171 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
172 RecvReq = GetLockedData(NextIrp, NextIrpSp);
173
174 AFD_DbgPrint(MID_TRACE,("Completing recv %p (%u)\n", NextIrp,
175 TotalBytesCopied));
176 UnlockBuffers( RecvReq->BufferArray,
177 RecvReq->BufferCount, FALSE );
178
179 /* Unexpected disconnect by the remote host or graceful disconnect */
180 Status = FCB->LastReceiveStatus;
181
182 NextIrp->IoStatus.Status = Status;
183 NextIrp->IoStatus.Information = 0;
184 if( NextIrp == Irp ) RetStatus = Status;
185 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
186 (void)IoSetCancelRoutine(NextIrp, NULL);
188 }
189 } else {
190 /* Kick the user that receive would be possible now */
191 /* XXX Not implemented yet */
192
193 AFD_DbgPrint(MID_TRACE,("FCB %p Receive data waiting %u\n",
194 FCB, FCB->Recv.Content));
195 /*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/
196
197 /* Try to clear some requests */
198 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
199 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
200 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
201 NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
202 RecvReq = GetLockedData(NextIrp, NextIrpSp);
203
204 AFD_DbgPrint(MID_TRACE,("RecvReq @ %p\n", RecvReq));
205
207 ( FCB, RecvReq, &TotalBytesCopied );
208
209 if( Status == STATUS_PENDING ) {
210 AFD_DbgPrint(MID_TRACE,("Ran out of data for %p\n", NextIrp));
211 InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV],
212 &NextIrp->Tail.Overlay.ListEntry);
213 break;
214 } else {
215 AFD_DbgPrint(MID_TRACE,("Completing recv %p (%u)\n", NextIrp,
216 TotalBytesCopied));
217 UnlockBuffers( RecvReq->BufferArray,
218 RecvReq->BufferCount, FALSE );
219 NextIrp->IoStatus.Status = Status;
220 NextIrp->IoStatus.Information = TotalBytesCopied;
221 if( NextIrp == Irp ) {
222 RetStatus = Status;
223 }
224 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
225 (void)IoSetCancelRoutine(NextIrp, NULL);
227 }
228 }
229 }
230
231 if( FCB->Recv.Content - FCB->Recv.BytesUsed &&
232 IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
233 FCB->PollState |= AFD_EVENT_RECEIVE;
234 FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
235 PollReeval( FCB->DeviceExt, FCB->FileObject );
236 }
237 else
238 {
239 FCB->PollState &= ~AFD_EVENT_RECEIVE;
240 }
241
242 /* Signal FD_CLOSE if no buffered data remains and the socket can't receive any more */
243 if (CantReadMore(FCB))
244 {
245 if (FCB->LastReceiveStatus == STATUS_SUCCESS)
246 {
247 FCB->PollState |= AFD_EVENT_DISCONNECT;
248 }
249 else
250 {
251 FCB->PollState |= AFD_EVENT_CLOSE;
252 }
253 FCB->PollStatus[FD_CLOSE_BIT] = FCB->LastReceiveStatus;
254 PollReeval(FCB->DeviceExt, FCB->FileObject);
255 }
256
257 AFD_DbgPrint(MID_TRACE,("RetStatus for irp %p is %x\n", Irp, RetStatus));
258
259 return RetStatus;
260}
static NTSTATUS TryToSatisfyRecvRequestFromBuffer(PAFD_FCB FCB, PAFD_RECV_INFO RecvReq, PUINT TotalBytesCopied)
Definition: read.c:94
static BOOLEAN CantReadMore(PAFD_FCB FCB)
Definition: read.c:88
#define AFD_EVENT_DISCONNECT
Definition: shared.h:206
#define AFD_EVENT_CLOSE
Definition: shared.h:208
#define FD_CLOSE_BIT
Definition: winsock2.h:303

Referenced by AfdConnectedSocketReadData(), MediaMonitor21040Dpc(), MediaMonitor21041Dpc(), MediaMonitor21143Dpc(), and ReceiveComplete().

◆ ReceiveComplete()

NTSTATUS NTAPI ReceiveComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 262 of file read.c.

265 {
267 PLIST_ENTRY NextIrpEntry;
268 PIRP NextIrp;
269 PAFD_RECV_INFO RecvReq;
270 PIO_STACK_LOCATION NextIrpSp;
271
273
274 AFD_DbgPrint(MID_TRACE,("Called\n"));
275
277 return STATUS_FILE_CLOSED;
278
279 ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
280 FCB->ReceiveIrp.InFlightRequest = NULL;
281
282 if( FCB->State == SOCKET_STATE_CLOSED ) {
283 /* Cleanup our IRP queue because the FCB is being destroyed */
284 while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
285 NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
286 NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
287 NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
288 RecvReq = GetLockedData(NextIrp, NextIrpSp);
290 NextIrp->IoStatus.Information = 0;
291 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
292 if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
293 (void)IoSetCancelRoutine(NextIrp, NULL);
295 }
297 return STATUS_FILE_CLOSED;
298 } else if( FCB->State == SOCKET_STATE_LISTENING ) {
299 AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
302 }
303
304 HandleReceiveComplete( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
305
307
309
310 return STATUS_SUCCESS;
311}
struct _AFD_FCB * PAFD_FCB
#define SOCKET_STATE_LISTENING
Definition: afd.h:77
static VOID HandleReceiveComplete(PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information)
Definition: read.c:53

◆ RefillSocketBuffer()

static VOID RefillSocketBuffer ( PAFD_FCB  FCB)
static

Definition at line 13 of file read.c.

14{
15 /* Make sure nothing's in flight first */
16 if (FCB->ReceiveIrp.InFlightRequest) return;
17
18 /* Now ensure that receive is still allowed */
19 if (FCB->TdiReceiveClosed) return;
20
21 /* Check if the buffer is full */
22 if (FCB->Recv.Content == FCB->Recv.Size)
23 {
24 /* If there are bytes used, we can solve this problem */
25 if (FCB->Recv.BytesUsed != 0)
26 {
27 /* Reposition the unused portion to the beginning of the receive window */
28 RtlMoveMemory(FCB->Recv.Window,
29 FCB->Recv.Window + FCB->Recv.BytesUsed,
30 FCB->Recv.Content - FCB->Recv.BytesUsed);
31
32 FCB->Recv.Content -= FCB->Recv.BytesUsed;
33 FCB->Recv.BytesUsed = 0;
34 }
35 else
36 {
37 /* No space in the buffer to receive */
38 return;
39 }
40 }
41
42 AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
43
44 TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
45 FCB->Connection.Object,
47 FCB->Recv.Window + FCB->Recv.Content,
48 FCB->Recv.Size - FCB->Recv.Content,
50 FCB );
51}
IO_COMPLETION_ROUTINE ReceiveComplete
Definition: afd.h:308
NTSTATUS TdiReceive(PIRP *Irp, PFILE_OBJECT TransportObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext)
Definition: tdi.c:976
#define TDI_RECEIVE_NORMAL
Definition: tdi.h:122
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by HandleReceiveComplete(), and TryToSatisfyRecvRequestFromBuffer().

◆ SatisfyPacketRecvRequest()

static NTSTATUS NTAPI SatisfyPacketRecvRequest ( PAFD_FCB  FCB,
PIRP  Irp,
PAFD_STORED_DATAGRAM  DatagramRecv,
PUINT  TotalBytesCopied 
)
static

Definition at line 314 of file read.c.

316 {
319 PAFD_RECV_INFO RecvReq =
321 UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
322 PAFD_MAPBUF Map;
323 BOOLEAN ExtraBuffers = CheckUnlockExtraBuffers(FCB, IrpSp);
324
325 Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
326 RecvReq->BufferCount +
327 (ExtraBuffers ? EXTRA_LOCK_BUFFERS : 0));
328
329 BytesToCopy = MIN( RecvReq->BufferArray[0].len, BytesAvailable );
330
331 AFD_DbgPrint(MID_TRACE,("BytesToCopy: %u len %u\n", BytesToCopy,
332 RecvReq->BufferArray[0].len));
333
334 if( Map[0].Mdl ) {
335 /* Copy the address */
336 if( ExtraBuffers && Map[1].Mdl && Map[2].Mdl ) {
337 AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
338
339 if( DatagramRecv->Address->TAAddressCount != 1 ) {
341 (MIN_TRACE,
342 ("Wierd address count %d\n",
343 DatagramRecv->Address->TAAddressCount));
344 }
345
346 AFD_DbgPrint(MID_TRACE,("Computing addr len\n"));
347
348 AddrLen = MIN(DatagramRecv->Address->Address->AddressLength +
349 sizeof(USHORT),
350 RecvReq->BufferArray[1].len);
351
352 AFD_DbgPrint(MID_TRACE,("Copying %u bytes of address\n", AddrLen));
353
354 Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, KernelMode );
355
356 AFD_DbgPrint(MID_TRACE,("Done mapping, copying address\n"));
357
359 &DatagramRecv->Address->Address->AddressType,
360 AddrLen );
361
362 MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl );
363
364 AFD_DbgPrint(MID_TRACE,("Copying address len\n"));
365
366 Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, KernelMode );
367 *((PINT)Map[2].BufferAddress) = AddrLen;
368 MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl );
369 }
370
371 AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n"));
372
373 Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode );
374
375 AFD_DbgPrint(MID_TRACE,("Buffer %d: %p:%u\n",
376 0,
377 Map[0].BufferAddress,
378 BytesToCopy));
379
381 DatagramRecv->Buffer,
382 BytesToCopy );
383
384 MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
385
386 *TotalBytesCopied = BytesToCopy;
387 }
388
389 if (*TotalBytesCopied == DatagramRecv->Len)
390 {
391 /* We copied the whole datagram */
392 Status = Irp->IoStatus.Status = STATUS_SUCCESS;
393 }
394 else
395 {
396 /* We only copied part of the datagram */
397 Status = Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
398 }
399
400 Irp->IoStatus.Information = *TotalBytesCopied;
401
402 if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
403 {
404 FCB->Recv.Content -= DatagramRecv->Len;
407 }
408
409 AFD_DbgPrint(MID_TRACE,("Done\n"));
410
411 return Status;
412}
unsigned char BOOLEAN
struct _AFD_MAPBUF * PAFD_MAPBUF
#define EXTRA_LOCK_BUFFERS
Definition: afd.h:95
#define MIN(x, y)
Definition: rdesktop.h:171
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:990
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
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define KernelMode
Definition: asm.h:34
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
PVOID BufferAddress
Definition: afd.h:104
UINT len
Definition: shared.h:17
USHORT AddressLength
Definition: tdi.h:338
USHORT AddressType
Definition: tdi.h:339
TA_ADDRESS Address[1]
Definition: tdi.h:377
LONG TAAddressCount
Definition: tdi.h:376
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
int * PINT
Definition: windef.h:177

Referenced by AfdConnectedSocketReadData(), AfdPacketSocketReadData(), and PacketSocketRecvComplete().

◆ TryToSatisfyRecvRequestFromBuffer()

static NTSTATUS TryToSatisfyRecvRequestFromBuffer ( PAFD_FCB  FCB,
PAFD_RECV_INFO  RecvReq,
PUINT  TotalBytesCopied 
)
static

Definition at line 94 of file read.c.

96 {
97 UINT i, BytesToCopy = 0, FcbBytesCopied = FCB->Recv.BytesUsed,
98 BytesAvailable =
99 FCB->Recv.Content - FCB->Recv.BytesUsed;
100 PAFD_MAPBUF Map;
101 *TotalBytesCopied = 0;
102
103
104 AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %u\n", BytesAvailable));
105
106 if( CantReadMore(FCB) ) return STATUS_SUCCESS;
107 if( !BytesAvailable ) return STATUS_PENDING;
108
109 Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
110
111 AFD_DbgPrint(MID_TRACE,("Buffer Count: %u @ %p\n",
112 RecvReq->BufferCount,
113 RecvReq->BufferArray));
114 for( i = 0;
115 RecvReq->BufferArray &&
116 BytesAvailable &&
117 i < RecvReq->BufferCount;
118 i++ ) {
120 MIN( RecvReq->BufferArray[i].len, BytesAvailable );
121
122 if( Map[i].Mdl ) {
124
125 AFD_DbgPrint(MID_TRACE,("Buffer %u: %p:%u\n",
126 i,
127 Map[i].BufferAddress,
128 BytesToCopy));
129
131 FCB->Recv.Window + FcbBytesCopied,
132 BytesToCopy );
133
134 MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
135
136 *TotalBytesCopied += BytesToCopy;
137 FcbBytesCopied += BytesToCopy;
138 BytesAvailable -= BytesToCopy;
139
140 if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK))
141 FCB->Recv.BytesUsed += BytesToCopy;
142 }
143 }
144
145 /* Issue another receive IRP to keep the buffer well stocked */
147
148 return STATUS_SUCCESS;
149}
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

Referenced by ReceiveActivity().