Implemented non-blocking recv and recvfrom.

Fixed address pass-through in afd.
Fixed some address cruft in udp and datagram regarding incoming
datagrams.

svn path=/trunk/; revision=11671
This commit is contained in:
Art Yerkes 2004-11-15 18:24:57 +00:00
parent f44ad86cf8
commit 28bfa5fcdd
19 changed files with 349 additions and 196 deletions

View file

@ -158,7 +158,6 @@ NTSTATUS AddrGetAddress(
return STATUS_INVALID_ADDRESS;
}
/*
* FUNCTION: Extract IP address from TDI address structure
* ARGUMENTS:

View file

@ -12,7 +12,10 @@
VOID DGDeliverData(
PADDRESS_FILE AddrFile,
PIP_ADDRESS Address,
PIP_ADDRESS SrcAddress,
PIP_ADDRESS DstAddress,
USHORT SrcPort,
USHORT DstPort,
PIP_PACKET IPPacket,
UINT DataSize)
/*
@ -58,29 +61,25 @@ VOID DGDeliverData(
PLIST_ENTRY CurrentEntry;
PDATAGRAM_RECEIVE_REQUEST Current;
BOOLEAN Found;
PTA_IP_ADDRESS RTAIPAddress;
TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n"));
/* Search receive request list to find a match */
Found = FALSE;
CurrentEntry = AddrFile->ReceiveQueue.Flink;
while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found))
{
while((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
if (!Current->RemotePort ||
AddrIsEqual(Address, &Current->RemoteAddress)) {
Found = TRUE;
/* FIXME: Maybe we should check if the buffer of this
receive request is large enough and if not, search
for another */
/* Remove the request from the queue */
RemoveEntryList(&Current->ListEntry);
break;
if( DstPort == AddrFile->Port ) {
Found = TRUE;
/* Remove the request from the queue */
RemoveEntryList(&Current->ListEntry);
break;
} else {
CurrentEntry = CurrentEntry->Flink;
}
CurrentEntry = CurrentEntry->Flink;
}
}
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
@ -92,10 +91,22 @@ VOID DGDeliverData(
RtlCopyMemory( Current->Buffer,
DataBuffer,
DataSize );
RTAIPAddress = (PTA_IP_ADDRESS)Current->ReturnInfo;
RTAIPAddress->TAAddressCount = 1;
RTAIPAddress->Address->AddressType = TDI_ADDRESS_TYPE_IP;
RTAIPAddress->Address->Address->sin_port = SrcPort;
TI_DbgPrint(MAX_TRACE, ("(A: %08x) Addr %08x Port %04x\n",
RTAIPAddress,
SrcAddress->Address.IPv4Address, SrcPort));
RtlCopyMemory( &RTAIPAddress->Address->Address->in_addr,
&SrcAddress->Address.IPv4Address,
sizeof(SrcAddress->Address.IPv4Address) );
/* Complete the receive request */
Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
exFreePool( Current );
}
}
else if (AddrFile->RegisteredReceiveDatagramHandler)
@ -107,15 +118,15 @@ VOID DGDeliverData(
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Address->Type == IP_ADDRESS_V4)
if (SrcAddress->Type == IP_ADDRESS_V4)
{
AddressLength = sizeof(IPv4_RAW_ADDRESS);
SourceAddress = &Address->Address.IPv4Address;
SourceAddress = &SrcAddress->Address.IPv4Address;
}
else /* (Address->Type == IP_ADDRESS_V6) */
{
AddressLength = sizeof(IPv6_RAW_ADDRESS);
SourceAddress = Address->Address.IPv6Address;
SourceAddress = SrcAddress->Address.IPv6Address;
}
Status = (*ReceiveHandler)(HandlerContext,

View file

@ -236,6 +236,15 @@ NTSTATUS UDPSendDatagram(
return STATUS_SUCCESS;
}
VOID UDPReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) {
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest =
(PDATAGRAM_RECEIVE_REQUEST)Context;
TI_DbgPrint(MAX_TRACE,("Called\n"));
ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count );
exFreePool( ReceiveRequest );
TI_DbgPrint(MAX_TRACE,("Done\n"));
}
NTSTATUS UDPReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
@ -278,7 +287,8 @@ NTSTATUS UDPReceiveDatagram(
/* Initialize a receive request */
/* Extract the remote address filter from the request (if any) */
if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress))
if ((ConnInfo->RemoteAddressLength != 0) &&
(ConnInfo->RemoteAddress))
{
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&ReceiveRequest->RemoteAddress,
@ -297,8 +307,11 @@ NTSTATUS UDPReceiveDatagram(
ReceiveRequest->ReturnInfo = ReturnInfo;
ReceiveRequest->Buffer = BufferData;
ReceiveRequest->BufferSize = ReceiveLength;
ReceiveRequest->Complete = Complete;
ReceiveRequest->Context = Context;
ReceiveRequest->UserComplete = Complete;
ReceiveRequest->UserContext = Context;
ReceiveRequest->Complete =
(PDATAGRAM_COMPLETION_ROUTINE)UDPReceiveComplete;
ReceiveRequest->Context = ReceiveRequest;
/* Queue receive request */
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
@ -343,7 +356,7 @@ VOID UDPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
PIPv4_HEADER IPv4Header;
PADDRESS_FILE AddrFile;
PUDP_HEADER UDPHeader;
PIP_ADDRESS DstAddress;
PIP_ADDRESS DstAddress, SrcAddress;
UINT DataSize, i;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
@ -353,6 +366,7 @@ VOID UDPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
case IP_ADDRESS_V4:
IPv4Header = IPPacket->Header;
DstAddress = &IPPacket->DstAddr;
SrcAddress = &IPPacket->SrcAddr;
break;
/* IPv6 packet */
@ -395,7 +409,10 @@ VOID UDPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
if (AddrFile) {
do {
DGDeliverData(AddrFile,
SrcAddress,
DstAddress,
UDPHeader->SourcePort,
UDPHeader->DestPort,
IPPacket,
DataSize);
} while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);

View file

@ -1,4 +1,4 @@
/* $Id: lock.c,v 1.5 2004/11/12 09:27:02 arty Exp $
/* $Id: lock.c,v 1.6 2004/11/15 18:24:57 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/lock.c
@ -36,19 +36,36 @@ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
Irp->MdlAddress = NULL;
}
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, BOOLEAN Write ) {
/* Note: We add an extra buffer if LockAddress is true. This allows us to
* treat the address buffer as an ordinary client buffer. It's only used
* for datagrams. */
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
PVOID AddressBuf, PINT AddressLen,
BOOLEAN Write, BOOLEAN LockAddress ) {
UINT i;
/* Copy the buffer array so we don't lose it */
UINT Size = sizeof(AFD_WSABUF) * Count;
UINT Lock = LockAddress ? 2 : 0;
UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
PMDL NewMdl;
AFD_DbgPrint(MID_TRACE,("Called\n"));
if( NewBuf ) {
PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count);
RtlCopyMemory( NewBuf, Buf, Size );
PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
if( LockAddress ) {
NewBuf[Count].buf = AddressBuf;
NewBuf[Count].len = *AddressLen;
Count++;
NewBuf[Count].buf = (PVOID)AddressLen;
NewBuf[Count].len = sizeof(*AddressLen);
Count++;
}
for( i = 0; i < Count; i++ ) {
AFD_DbgPrint(MID_TRACE,("Locking buffer %d (%x:%d)\n",
i, NewBuf[i].buf, NewBuf[i].len));
@ -82,11 +99,12 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, BOOLEAN Write ) {
return NewBuf;
}
VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count ) {
PAFD_MAPBUF Map = (PAFD_MAPBUF)(Buf + Count);
VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address ) {
UINT Lock = Address ? 2 : 0;
PAFD_MAPBUF Map = (PAFD_MAPBUF)(Buf + Count + Lock);
UINT i;
for( i = 0; i < Count; i++ ) {
for( i = 0; i < Count + Lock; i++ ) {
if( Map[i].Mdl ) {
MmUnlockPages( Map[i].Mdl );
IoFreeMdl( Map[i].Mdl );

View file

@ -1,4 +1,4 @@
/* $Id: read.c,v 1.9 2004/11/14 19:45:16 arty Exp $
/* $Id: read.c,v 1.10 2004/11/15 18:24:57 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/read.c
@ -128,7 +128,8 @@ NTSTATUS DDKAPI ReceiveComplete
} else {
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
TotalBytesCopied));
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
UnlockBuffers( RecvReq->BufferArray,
RecvReq->BufferCount, FALSE );
NextIrp->IoStatus.Status = Status;
NextIrp->IoStatus.Information = TotalBytesCopied;
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
@ -200,7 +201,8 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
RecvReq->BufferCount,
TRUE );
NULL, NULL,
TRUE, FALSE );
/* Launch a new recv request if we have no data */
@ -228,8 +230,13 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = TryToSatisfyRecvRequestFromBuffer
( FCB, RecvReq, &TotalBytesCopied );
if( Status != STATUS_PENDING ) {
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
if( Status != STATUS_PENDING || RecvReq->AfdFlags & AFD_IMMEDIATE ) {
if( Status == STATUS_PENDING ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
Status = STATUS_CANT_WAIT;
TotalBytesCopied = 0;
}
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
return UnlockAndMaybeComplete( FCB, Status, Irp,
TotalBytesCopied, NULL, TRUE );
} else {
@ -246,10 +253,12 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
PAFD_RECV_INFO RecvReq =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len;
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
PAFD_MAPBUF Map;
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
Map = (PAFD_MAPBUF)(RecvReq->BufferArray +
RecvReq->BufferCount +
EXTRA_LOCK_BUFFERS);
BytesToCopy =
MIN( RecvReq->BufferArray[0].len, BytesAvailable );
@ -258,6 +267,44 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
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",
@ -273,15 +320,18 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
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;
}
@ -317,6 +367,11 @@ PacketSocketRecvComplete(
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;
@ -325,19 +380,17 @@ PacketSocketRecvComplete(
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] );
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));
AFD_DbgPrint(MID_TRACE,("RecvReq->BufferArray %x\n",
RecvReq->BufferArray[0]));
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
@ -345,18 +398,22 @@ PacketSocketRecvComplete(
&DatagramRecv->ListEntry );
Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
NextIrp->IoStatus.Information = DatagramRecv->Len;
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
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 );
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
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;
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
@ -390,7 +447,7 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
NTSTATUS Status = STATUS_SUCCESS;
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PAFD_RECV_INFO RecvReq;
PAFD_RECV_INFO_UDP RecvReq;
PLIST_ENTRY ListEntry;
PAFD_STORED_DATAGRAM DatagramRecv;
@ -405,9 +462,13 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
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,
TRUE );
RecvReq->Address,
RecvReq->AddressLength,
TRUE, TRUE );
if( !IsListEmpty( &FCB->DatagramList ) ) {
ListEntry = RemoveHeadList( &FCB->DatagramList );
@ -431,6 +492,10 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
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;
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
} else {
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
}

View file

@ -1,4 +1,4 @@
/* $Id: select.c,v 1.4 2004/09/23 06:42:16 arty Exp $
/* $Id: select.c,v 1.5 2004/11/15 18:24:57 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/select.c
@ -56,14 +56,22 @@ ScanForImmediateTrigger( PAFD_HANDLE HandleArray,
if( NT_SUCCESS(Status) ) {
FCB = FileObject->FsContext;
/* Check select bits */
if( !SocketAcquireStateLock( FCB ) )
AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
if( !SocketAcquireStateLock( FCB ) ) {
AFD_DbgPrint(MID_TRACE,("Failed to get a socket state\n"));
Status = STATUS_UNSUCCESSFUL;
if( NT_SUCCESS(Status) ) {
} else {
AFD_DbgPrint(MID_TRACE,("Got a socket state\n"));
Status = STATUS_SUCCESS;
HandleArray[i].Status =
FCB->PollState & HandleArray[i].Events;
if( HandleArray[i].Status ) ShouldReturnNow = TRUE;
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
SocketStateUnlock( FCB );
AFD_DbgPrint(MID_TRACE,("Unlocked\n"));
}
}
}
@ -114,7 +122,9 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
KIRQL OldIrql;
UINT HandlesSignalled;
AFD_DbgPrint(MID_TRACE,("Called\n"));
AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n",
PollReq->HandleCount,
(INT)(PollReq->Timeout.QuadPart * -1)));
Status = ScanForImmediateTrigger( PollReq->Handles,
PollReq->HandleCount,
@ -196,6 +206,8 @@ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
} else {
FCB = FileObject->FsContext;
AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
if( !SocketAcquireStateLock( FCB ) ) {
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
SignalSocket( Poll, PollReq, i );
@ -204,6 +216,7 @@ BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
PollReq->Handles[i].Events & FCB->PollState;
if( PollReq->Handles[i].Status )
SignalSocket( Poll, PollReq, i );
SocketStateUnlock( FCB );
}
return TRUE;
}

View file

@ -1,4 +1,4 @@
/* $Id: tdiconn.c,v 1.4 2004/10/03 21:44:42 arty Exp $
/* $Id: tdiconn.c,v 1.5 2004/11/15 18:24:57 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/tdiconn.c
@ -39,6 +39,13 @@ VOID TaCopyAddressInPlace( PTA_ADDRESS Target,
RtlCopyMemory( Target, Source, AddrLen );
}
PTA_ADDRESS TaCopyAddress( PTA_ADDRESS Source ) {
UINT AddrLen = TaLengthOfAddress( Source );
PVOID Buffer = ExAllocatePool( NonPagedPool, AddrLen );
RtlCopyMemory( Buffer, Source, AddrLen );
return Buffer;
}
VOID TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target,
PTRANSPORT_ADDRESS Source ) {
UINT AddrLen = TaLengthOfTransportAddress( Source );

View file

@ -1,4 +1,4 @@
/* $Id: write.c,v 1.10 2004/11/12 07:34:56 arty Exp $
/* $Id: write.c,v 1.11 2004/11/15 18:24:57 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/write.c
@ -53,7 +53,8 @@ NTSTATUS DDKAPI SendComplete
SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
UnlockBuffers( SendReq->BufferArray,
SendReq->BufferCount );
SendReq->BufferCount,
FALSE );
NextIrp->IoStatus.Status = Status;
NextIrp->IoStatus.Information = 0;
@ -128,7 +129,7 @@ NTSTATUS DDKAPI SendComplete
}
if( TotalBytesCopied > 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
if( Status == STATUS_PENDING )
Status = STATUS_SUCCESS;
@ -169,8 +170,14 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("Socket state %d\n", FCB->State));
if( FCB->State != SOCKET_STATE_CONNECTED ) {
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
return UnlockAndMaybeComplete
( FCB, STATUS_CANT_WAIT, Irp, 0, NULL, TRUE );
} else {
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
}
}
AFD_DbgPrint(MID_TRACE,("We already have %d bytes waiting.\n",
@ -178,7 +185,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
SendReq->BufferCount,
FALSE );
NULL, NULL,
FALSE, FALSE );
AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n",
FCB->Send.BytesUsed));
@ -212,7 +220,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
}
if( TotalBytesEncountered == 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
return UnlockAndMaybeComplete
@ -222,7 +230,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
if( TotalBytesCopied > 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
FCB->SendIrp.InFlightRequest = (PVOID)1; /* Placeholder */
@ -250,8 +258,14 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
}
}
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
return UnlockAndMaybeComplete
( FCB, STATUS_CANT_WAIT, Irp, 0, NULL, TRUE );
} else {
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
}
}
NTSTATUS DDKAPI PacketSocketSendComplete

View file

@ -1,4 +1,4 @@
/* $Id: afd.h,v 1.22 2004/11/14 19:45:16 arty Exp $
/* $Id: afd.h,v 1.23 2004/11/15 18:24:57 arty Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -56,6 +56,10 @@
#define IN_FLIGHT_REQUESTS 3
#define EXTRA_LOCK_BUFFERS 2 /* Number of extra buffers needed
* for ancillary data on packet
* requests. */
#define DEFAULT_SEND_WINDOW_SIZE 16384
#define DEFAULT_RECEIVE_WINDOW_SIZE 16384
@ -104,7 +108,7 @@ typedef struct _AFD_DATA_WINDOW {
typedef struct _AFD_STORED_DATAGRAM {
LIST_ENTRY ListEntry;
UINT Len;
PTA_ADDRESS Address;
PTRANSPORT_ADDRESS Address;
CHAR Buffer[1];
} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
@ -170,8 +174,10 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
/* lock.c */
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, BOOLEAN Write );
VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count );
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
PVOID AddressBuf, PINT AddressLen,
BOOLEAN Write, BOOLEAN LockAddress );
VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address );
UINT SocketAcquireStateLock( PAFD_FCB FCB );
NTSTATUS DDKAPI UnlockAndMaybeComplete
( PAFD_FCB FCB, NTSTATUS Status, PIRP Irp,

View file

@ -11,6 +11,7 @@ PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress );
UINT TaLengthOfAddress( PTA_ADDRESS Addr );
UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr );
VOID TaCopyAddressInPlace( PTA_ADDRESS Target, PTA_ADDRESS Source );
PTA_ADDRESS TaCopyAddress( PTA_ADDRESS Source );
VOID TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target,
PTRANSPORT_ADDRESS Source );
UINT TdiAddressSizeFromType( UINT Type );

View file

@ -10,50 +10,15 @@
#include <titypes.h>
VOID DGSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest);
VOID DGDeliverData(
PADDRESS_FILE AddrFile,
PIP_ADDRESS Address,
PIP_ADDRESS SrcAddress,
PIP_ADDRESS DstAddress,
USHORT SrcPort,
USHORT DstPort,
PIP_PACKET IPPacket,
UINT DataSize);
VOID DGCancelSendRequest(
PADDRESS_FILE AddrFile,
PVOID Context);
VOID DGCancelReceiveRequest(
PADDRESS_FILE AddrFile,
PVOID Context);
NTSTATUS DGTransmit(
PADDRESS_FILE AddressFile,
PDATAGRAM_SEND_REQUEST SendRequest);
NTSTATUS DGSendDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR BufferData,
ULONG DataSize,
PULONG DataUsed );
NTSTATUS DGReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived);
NTSTATUS DGStartup(
VOID);
NTSTATUS DGShutdown(
VOID);
#endif /* __DATAGRAM_H */
/* EOF */

View file

@ -113,14 +113,16 @@ typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)(
typedef DATAGRAM_COMPLETION_ROUTINE PDATAGRAM_COMPLETION_ROUTINE;
typedef struct _DATAGRAM_RECEIVE_REQUEST {
LIST_ENTRY ListEntry; /* Entry on list */
LIST_ENTRY ListEntry; /* Entry on list */
IP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */
USHORT RemotePort; /* Remote port we receive from (0 means any) */
PTDI_CONNECTION_INFORMATION ReturnInfo; /* Return information */
PCHAR Buffer; /* Pointer to receive buffer */
ULONG BufferSize; /* Size of Buffer */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
USHORT RemotePort; /* Remote port we receive from (0 means any) */
PTDI_CONNECTION_INFORMATION ReturnInfo;/* Return information */
PCHAR Buffer; /* Pointer to receive buffer */
ULONG BufferSize; /* Size of Buffer */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
DATAGRAM_COMPLETION_ROUTINE UserComplete; /* Completion routine */
PVOID UserContext; /* Pointer to context information */
} DATAGRAM_RECEIVE_REQUEST, *PDATAGRAM_RECEIVE_REQUEST;
/* Datagram build routine prototype */

View file

@ -725,11 +725,11 @@ NTSTATUS DispTdiReceiveDatagram(
Status = UDPReceiveDatagram(
Request.Handle.AddressHandle,
DgramInfo->ReceiveDatagramInformation,
DgramInfo->ReceiveDatagramInformation->RemoteAddress,
DataBuffer,
DgramInfo->ReceiveLength,
DgramInfo->ReceiveFlags,
DgramInfo->ReturnDatagramInformation,
DgramInfo->ReturnDatagramInformation->RemoteAddress,
&BytesReceived,
(PDATAGRAM_COMPLETION_ROUTINE)DispDataRequestComplete,
Irp);

View file

@ -9,7 +9,7 @@
*/
#include "precomp.h"
#define NDEBUG
//#define NDEBUG
#ifndef NDEBUG
DWORD DebugTraceLevel = 0x7fffffff;

View file

@ -7,6 +7,7 @@
#ifndef __MSAFD_H
#define __MSAFD_H
#include <roscfg.h>
#include <stdlib.h>
#include <windows.h>
#include <ddk/ntddk.h>

View file

@ -9,13 +9,15 @@
* CSH 01/09-2000 Created
* Alex 16/07/2004 - Complete Rewrite
*/
#include <roscfg.h>
#include <string.h>
#include <msafd.h>
#include <helpers.h>
#include <rosrtl/string.h>
#ifdef DBG
DWORD DebugTraceLevel = DEBUG_ULTRA;
//DWORD DebugTraceLevel = DEBUG_ULTRA;
DWORD DebugTraceLevel = 0;
#endif /* DBG */
HANDLE GlobalHeap;
@ -83,6 +85,7 @@ WSPSocket(
/* Check for error */
if (Status != NO_ERROR) {
AFD_DbgPrint(MID_TRACE,("SockGetTdiName: Status %x\n", Status));
goto error;
}
@ -975,6 +978,39 @@ WSPGetPeerName(
return 0;
}
INT
WSPAPI
WSPIoctl(
IN SOCKET Handle,
IN DWORD dwIoControlCode,
IN LPVOID lpvInBuffer,
IN DWORD cbInBuffer,
OUT LPVOID lpvOutBuffer,
IN DWORD cbOutBuffer,
OUT LPDWORD lpcbBytesReturned,
IN LPWSAOVERLAPPED lpOverlapped,
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
IN LPWSATHREADID lpThreadId,
OUT LPINT lpErrno)
{
PSOCKET_INFORMATION Socket = NULL;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
switch( dwIoControlCode ) {
case FIONBIO:
if( cbInBuffer < sizeof(INT) ) return -1;
Socket->SharedData.NonBlocking = *((PINT)lpvInBuffer) ? 1 : 0;
AFD_DbgPrint(MID_TRACE,("[%x] Set nonblocking %d\n",
Handle, Socket->SharedData.NonBlocking));
return 0;
default:
return -1;
}
}
INT
WSPAPI
WSPStartup(

View file

@ -92,6 +92,7 @@ SockGetTdiName(
for (Transport = Transports;
*Transports != 0;
Transport += wcslen(Transport) + 1) {
AFD_DbgPrint(MID_TRACE, ("Transport: %S\n", Transports));
/* See what mapping this Transport supports */
Status = SockLoadTransportMapping(Transport, &Mapping);

View file

@ -48,6 +48,11 @@ WSPRecv(
PVOID APCFunction;
HANDLE Event;
HANDLE SockEvent;
PSOCKET_INFORMATION Socket;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
@ -58,7 +63,7 @@ WSPRecv(
RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
RecvInfo.BufferCount = dwBufferCount;
RecvInfo.TdiFlags = 0;
RecvInfo.AfdFlags = 0;
RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
/* Set the TDI Flags */
if (*ReceiveFlags == 0) {
@ -137,34 +142,36 @@ WSPRecv(
/* Return the Flags */
*ReceiveFlags = 0;
switch (Status) {
case STATUS_CANT_WAIT:
return WSAEWOULDBLOCK;
case STATUS_SUCCESS:
break;
case STATUS_PENDING :
return WSA_IO_PENDING;
case STATUS_BUFFER_OVERFLOW:
return WSAEMSGSIZE;
case STATUS_RECEIVE_EXPEDITED:
*ReceiveFlags = MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL_EXPEDITED :
*ReceiveFlags = MSG_PARTIAL | MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL :
*ReceiveFlags = MSG_PARTIAL;
break;
}
/* Return Number of bytes Read */
*lpNumberOfBytesRead = (DWORD)IOSB->Information;
/* Success */
return STATUS_SUCCESS;
case STATUS_SUCCESS:
break;
case STATUS_PENDING :
return WSA_IO_PENDING;
case STATUS_BUFFER_OVERFLOW:
return WSAEMSGSIZE;
case STATUS_RECEIVE_EXPEDITED:
*ReceiveFlags = MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL_EXPEDITED :
*ReceiveFlags = MSG_PARTIAL | MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL :
*ReceiveFlags = MSG_PARTIAL;
break;
}
/* Return Number of bytes Read */
*lpNumberOfBytesRead = (DWORD)IOSB->Information;
/* Success */
return STATUS_SUCCESS;
}
int
@ -190,6 +197,10 @@ WSPRecvFrom(
PVOID APCFunction;
HANDLE Event;
HANDLE SockEvent;
PSOCKET_INFORMATION Socket;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
@ -200,7 +211,7 @@ WSPRecvFrom(
RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
RecvInfo.BufferCount = dwBufferCount;
RecvInfo.TdiFlags = 0;
RecvInfo.AfdFlags = 0;
RecvInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
RecvInfo.AddressLength = SocketAddressLength;
RecvInfo.Address = SocketAddress;
@ -281,27 +292,29 @@ WSPRecvFrom(
/* Return the Flags */
*ReceiveFlags = 0;
switch (Status) {
case STATUS_SUCCESS:
break;
case STATUS_CANT_WAIT:
return WSAEWOULDBLOCK;
case STATUS_PENDING :
return WSA_IO_PENDING;
case STATUS_BUFFER_OVERFLOW:
return WSAEMSGSIZE;
case STATUS_RECEIVE_EXPEDITED:
*ReceiveFlags = MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL_EXPEDITED :
*ReceiveFlags = MSG_PARTIAL | MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL :
*ReceiveFlags = MSG_PARTIAL;
break;
case STATUS_SUCCESS:
break;
case STATUS_PENDING :
return WSA_IO_PENDING;
case STATUS_BUFFER_OVERFLOW:
return WSAEMSGSIZE;
case STATUS_RECEIVE_EXPEDITED:
*ReceiveFlags = MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL_EXPEDITED :
*ReceiveFlags = MSG_PARTIAL | MSG_OOB;
break;
case STATUS_RECEIVE_PARTIAL :
*ReceiveFlags = MSG_PARTIAL;
break;
}
/* Return Number of bytes Read */
@ -333,6 +346,10 @@ WSPSend(
PVOID APCFunction;
HANDLE Event;
HANDLE SockEvent;
PSOCKET_INFORMATION Socket;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
@ -345,7 +362,7 @@ WSPSend(
SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
SendInfo.BufferCount = dwBufferCount;
SendInfo.TdiFlags = 0;
SendInfo.AfdFlags = 0;
SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
/* Set the TDI Flags */
if (iFlags) {
@ -441,7 +458,6 @@ WSPSendTo(
PIO_STATUS_BLOCK IOSB;
IO_STATUS_BLOCK DummyIOSB;
AFD_SEND_INFO_UDP SendInfo;
PSOCKET_INFORMATION Socket;
NTSTATUS Status;
PVOID APCContext;
PVOID APCFunction;
@ -451,15 +467,17 @@ WSPSendTo(
PSOCKADDR BindAddress;
INT BindAddressLength;
HANDLE SockEvent;
PSOCKET_INFORMATION Socket;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
NULL, 1, FALSE );
if( !NT_SUCCESS(Status) ) return -1;
/* Get the Socket Structure associate to this Socket*/
Socket = GetSocketStructure(Handle);
/* Bind us First */
if (Socket->SharedData.State == SocketOpen) {
@ -482,7 +500,7 @@ WSPSendTo(
/* Set up Structure */
SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
SendInfo.AfdFlags = 0;
SendInfo.AfdFlags = Socket->SharedData.NonBlocking ? AFD_IMMEDIATE : 0;
SendInfo.BufferCount = dwBufferCount;
SendInfo.RemoteAddress = RemoteAddress;
SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength;

View file

@ -97,27 +97,6 @@ WSPGetSockOpt(
}
INT
WSPAPI
WSPIoctl(
IN SOCKET s,
IN DWORD dwIoControlCode,
IN LPVOID lpvInBuffer,
IN DWORD cbInBuffer,
OUT LPVOID lpvOutBuffer,
IN DWORD cbOutBuffer,
OUT LPDWORD lpcbBytesReturned,
IN LPWSAOVERLAPPED lpOverlapped,
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
IN LPWSATHREADID lpThreadId,
OUT LPINT lpErrno)
{
UNIMPLEMENTED
return 0;
}
SOCKET
WSPAPI
WSPJoinLeaf(