📄 read.c
字号:
InsertTailList( &FCB->PendingIrpList[FUNCTION_RECV],
&Irp->Tail.Overlay.ListEntry );
/************ From this point, the IRP is not ours ************/
Status = ReceiveActivity( FCB, Irp );
if( Status == STATUS_PENDING && RecvReq->AfdFlags & AFD_IMMEDIATE ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
Status = STATUS_CANT_WAIT;
TotalBytesCopied = 0;
RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
return UnlockAndMaybeComplete( FCB, Status, Irp,
TotalBytesCopied, NULL, TRUE );
} else if( Status == STATUS_PENDING ) {
AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
IoMarkIrpPending( Irp );
} else {
AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
}
SocketStateUnlock( FCB );
return Status;
}
static NTSTATUS STDCALL
SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
PAFD_STORED_DATAGRAM DatagramRecv,
PUINT TotalBytesCopied ) {
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
PAFD_RECV_INFO RecvReq =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
PAFD_MAPBUF Map;
Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
RecvReq->BufferCount +
EXTRA_LOCK_BUFFERS);
BytesToCopy =
MIN( RecvReq->BufferArray[0].len, BytesAvailable );
AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
RecvReq->BufferArray[0].len));
if( Map[0].Mdl ) {
/* Copy the address */
if( Map[1].Mdl && Map[2].Mdl ) {
AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
if( DatagramRecv->Address->TAAddressCount != 1 ) {
AFD_DbgPrint
(MID_TRACE,
("Wierd address count %d\n",
DatagramRecv->Address->TAAddressCount));
}
AFD_DbgPrint(MID_TRACE,("Computing addr len\n"));
AddrLen = MIN(DatagramRecv->Address->Address->AddressLength +
sizeof(USHORT),
RecvReq->BufferArray[1].len);
AFD_DbgPrint(MID_TRACE,("Copying %d bytes of address\n", AddrLen));
Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, KernelMode );
AFD_DbgPrint(MID_TRACE,("Done mapping, copying address\n"));
RtlCopyMemory( Map[1].BufferAddress,
&DatagramRecv->Address->Address->AddressType,
AddrLen );
MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl );
AFD_DbgPrint(MID_TRACE,("Copying address len\n"));
Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, KernelMode );
*((PINT)Map[2].BufferAddress) = AddrLen;
MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl );
}
AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n"));
Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode );
AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
0,
Map[0].BufferAddress,
BytesToCopy));
/* OskitDumpBuffer
( FCB->Recv.Window + FCB->Recv.BytesUsed, BytesToCopy ); */
RtlCopyMemory( Map[0].BufferAddress,
FCB->Recv.Window + FCB->Recv.BytesUsed,
BytesToCopy );
MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl );
FCB->Recv.BytesUsed = 0;
*TotalBytesCopied = BytesToCopy;
}
Status = Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = BytesToCopy;
ExFreePool( DatagramRecv->Address );
ExFreePool( DatagramRecv );
AFD_DbgPrint(MID_TRACE,("Done\n"));
return Status;
}
NTSTATUS NTAPI
PacketSocketRecvComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context ) {
NTSTATUS Status = STATUS_SUCCESS;
PAFD_FCB FCB = Context;
PIRP NextIrp;
PIO_STACK_LOCATION NextIrpSp;
PLIST_ENTRY ListEntry;
PAFD_RECV_INFO RecvReq;
PAFD_STORED_DATAGRAM DatagramRecv;
UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM );
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return STATUS_UNSUCCESSFUL;
FCB->ReceiveIrp.InFlightRequest = NULL;
if( FCB->State == SOCKET_STATE_CLOSED ) {
SocketStateUnlock( FCB );
DestroySocket( FCB );
return STATUS_SUCCESS;
}
DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
if( DatagramRecv ) {
DatagramRecv->Len = Irp->IoStatus.Information;
RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
DatagramRecv->Len );
AFD_DbgPrint(MID_TRACE,("Received (A %x)\n",
FCB->AddressFrom->RemoteAddress));
DatagramRecv->Address =
TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );
InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
} else Status = STATUS_NO_MEMORY;
/* Satisfy as many requests as we can */
while( NT_SUCCESS(Status) &&
!IsListEmpty( &FCB->DatagramList ) &&
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
ListEntry = RemoveHeadList( &FCB->DatagramList );
DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
ListEntry );
ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
RecvReq, DatagramRecv));
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
InsertHeadList( &FCB->DatagramList,
&DatagramRecv->ListEntry );
Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
NextIrp->IoStatus.Information = DatagramRecv->Len;
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
} else {
AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
Status = SatisfyPacketRecvRequest
( FCB, NextIrp, DatagramRecv,
(PUINT)&NextIrp->IoStatus.Information );
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
AFD_DbgPrint(MID_TRACE,("Completing\n"));
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
}
}
if( !IsListEmpty( &FCB->DatagramList ) ) {
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
FCB->PollState |= AFD_EVENT_RECEIVE;
} else
FCB->PollState &= ~AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
/* Now relaunch the datagram request */
SocketCalloutEnter( FCB );
Status = TdiReceiveDatagram
( &FCB->ReceiveIrp.InFlightRequest,
FCB->AddressFile.Object,
0,
FCB->Recv.Window,
FCB->Recv.Size,
FCB->AddressFrom,
&FCB->ReceiveIrp.Iosb,
PacketSocketRecvComplete,
FCB );
SocketCalloutLeave( FCB );
}
SocketStateUnlock( FCB );
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
NTSTATUS Status = STATUS_SUCCESS;
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PAFD_RECV_INFO_UDP RecvReq;
PLIST_ENTRY ListEntry;
PAFD_STORED_DATAGRAM DatagramRecv;
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
FCB->EventsFired &= ~AFD_EVENT_RECEIVE;
/* Check that the socket is bound */
if( FCB->State != SOCKET_STATE_BOUND )
return UnlockAndMaybeComplete
( FCB, STATUS_UNSUCCESSFUL, Irp, 0, NULL, FALSE );
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );
AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
RecvReq->BufferCount,
RecvReq->Address,
RecvReq->AddressLength,
TRUE, TRUE );
if( !IsListEmpty( &FCB->DatagramList ) ) {
ListEntry = RemoveHeadList( &FCB->DatagramList );
DatagramRecv = CONTAINING_RECORD
( ListEntry, AFD_STORED_DATAGRAM, ListEntry );
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
InsertHeadList( &FCB->DatagramList,
&DatagramRecv->ListEntry );
Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = DatagramRecv->Len;
if( IsListEmpty( &FCB->DatagramList ) )
FCB->PollState &= ~AFD_EVENT_RECEIVE;
else
FCB->PollState |= AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return UnlockAndMaybeComplete
( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
} else {
Status = SatisfyPacketRecvRequest
( FCB, Irp, DatagramRecv,
(PUINT)&Irp->IoStatus.Information );
if( IsListEmpty( &FCB->DatagramList ) )
FCB->PollState &= ~AFD_EVENT_RECEIVE;
else
FCB->PollState |= AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return UnlockAndMaybeComplete
( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
}
} else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
Status = STATUS_CANT_WAIT;
PollReeval( FCB->DeviceExt, FCB->FileObject );
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
} else {
PollReeval( FCB->DeviceExt, FCB->FileObject );
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -