5 removed + 27 modified, total 32 files
reactos/drivers/net/afd
diff -u -r1.10 -r1.11
--- makefile 2 Mar 2004 18:18:13 -0000 1.10
+++ makefile 18 Jul 2004 22:49:16 -0000 1.11
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.10 2004/03/02 18:18:13 navaraf Exp $
+# $Id: makefile,v 1.11 2004/07/18 22:49:16 arty Exp $
PATH_TO_TOP = ../../..
@@ -6,17 +6,21 @@
TARGET_NAME = afd
-TARGET_CFLAGS = -I./include -DDBG -D__USE_W32API -Werror -Wall
+TARGET_CFLAGS = -I./include -I$(PATH_TO_TOP)/w32api/include/ddk -I$(PATH_TO_TOP)/include/afd -DDBG -D__USE_W32API -Werror -Wall
TARGET_OBJECTS = \
- afd/afd.o \
- afd/dispatch.o \
- afd/event.o \
- afd/opnclose.o \
- afd/rdwr.o \
- afd/routines.o \
- afd/tdi.o \
- afd/tdiconn.o
+ afd/bind.o \
+ afd/connect.o \
+ afd/context.o \
+ afd/info.o \
+ afd/listen.o \
+ afd/lock.o \
+ afd/main.o \
+ afd/read.o \
+ afd/select.o \
+ afd/tdi.o \
+ afd/tdiconn.o \
+ afd/write.o
include $(PATH_TO_TOP)/rules.mak
reactos/drivers/net/afd/afd
diff -N bind.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ bind.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,87 @@
+/* $Id: bind.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/bind.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) {
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ if( FCB->LocalAddress ) {
+ Status = TdiOpenAddressFile
+ ( &FCB->TdiDeviceName,
+ FCB->LocalAddress,
+ &FCB->AddressFile.Handle,
+ &FCB->AddressFile.Object );
+ }
+
+ if( !NT_SUCCESS(Status) ) {
+ TdiCloseDevice( &FCB->AddressFile.Handle,
+ FCB->AddressFile.Object );
+ RtlZeroMemory( &FCB->AddressFile, sizeof( FCB->AddressFile ) );
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+
+ return Status;
+}
+
+NTSTATUS STDCALL
+AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PAFD_BIND_DATA BindReq;
+
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+ if( !(BindReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
+ Irp, 0, NULL, FALSE );
+
+ FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
+
+ if( FCB->LocalAddress )
+ Status = WarmSocketForBind( FCB );
+ else Status = STATUS_NO_MEMORY;
+
+ if( NT_SUCCESS(Status) )
+ FCB->State = SOCKET_STATE_BOUND;
+
+ if( FCB->Flags & SGID_CONNECTIONLESS ) {
+ /* This will be the from address for subsequent recvfrom calls */
+ TdiBuildConnectionInfo( &FCB->AddressFrom,
+ &FCB->LocalAddress->Address[0] );
+ /* Allocate our backup buffer */
+ FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size );
+ FCB->PollState |= AFD_EVENT_SEND;
+ /* A datagram socket is always sendable */
+
+ Status = TdiReceiveDatagram
+ ( &FCB->ReceiveIrp.InFlightRequest,
+ FCB->AddressFile.Object,
+ 0,
+ FCB->Recv.Window,
+ FCB->Recv.Size,
+ FCB->AddressFrom,
+ &FCB->ReceiveIrp.Iosb,
+ PacketSocketRecvComplete,
+ FCB );
+ }
+
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
+}
+
reactos/drivers/net/afd/afd
diff -N connect.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ connect.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,201 @@
+/* $Id: connect.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/connect.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
+ NTSTATUS Status = TdiOpenConnectionEndpointFile
+ ( &FCB->TdiDeviceName,
+ &FCB->Connection.Handle,
+ &FCB->Connection.Object );
+
+ if( NT_SUCCESS(Status) ) {
+ Status = TdiAssociateAddressFile
+ ( FCB->AddressFile.Handle,
+ FCB->Connection.Object );
+ }
+
+ if( !NT_SUCCESS(Status) ) {
+ TdiCloseDevice( &FCB->Connection.Handle,
+ FCB->Connection.Object );
+ RtlZeroMemory( &FCB->Connection, sizeof(FCB->Connection) );
+ }
+
+ return Status;
+}
+
+NTSTATUS DDKAPI StreamSocketConnectComplete
+( PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context ) {
+ NTSTATUS Status = Irp->IoStatus.Status;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ PAFD_FCB FCB = (PAFD_FCB)Context;
+ PLIST_ENTRY NextIrpEntry;
+ PIRP NextIrp;
+
+ AFD_DbgPrint(MID_TRACE,("Called: FCB %x, FO %x\n",
+ Context, FCB->FileObject));
+
+ /* Check the result of the connect operation */
+ /* Since the previous does not return until we come through here, we do
+ * not need to relock. */
+ /* if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); */
+
+ AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n",
+ Irp->IoStatus.Status));
+
+ if( NT_SUCCESS(Irp->IoStatus.Status) ) {
+ FCB->PollState |= AFD_EVENT_CONNECT;
+ FCB->State = SOCKET_STATE_CONNECTED;
+ AFD_DbgPrint(MID_TRACE,("Going to connected state %d\n", FCB->State));
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ } else {
+ FCB->PollState |= AFD_EVENT_CONNECT_FAIL;
+ AFD_DbgPrint(MID_TRACE,("Going to bound state\n"));
+ FCB->State = SOCKET_STATE_BOUND;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ }
+
+ /* Succeed pending irps on the FUNCTION_CONNECT list */
+ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) {
+ NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
+ NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+ AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp));
+ NextIrp->IoStatus.Status = Status;
+ NextIrp->IoStatus.Information = 0;
+ IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+ }
+
+ if( NT_SUCCESS(Status) ) {
+ /* Allocate the receive area and start receiving */
+ FCB->Recv.Window =
+ ExAllocatePool( NonPagedPool, FCB->Recv.Size );
+ FCB->Send.Window =
+ ExAllocatePool( NonPagedPool, FCB->Send.Size );
+
+ if( FCB->Recv.Window ) {
+ Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
+ IrpSp->FileObject,
+ TDI_RECEIVE_NORMAL,
+ FCB->Recv.Window,
+ FCB->Recv.Size,
+ &FCB->ReceiveIrp.Iosb,
+ ReceiveComplete,
+ FCB );
+ }
+
+ if( FCB->Send.Window &&
+ !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
+ NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
+ NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP,
+ Tail.Overlay.ListEntry);
+ AFD_DbgPrint(MID_TRACE,("Launching send request %x\n", NextIrp));
+ Status = AfdConnectedSocketWriteData
+ ( DeviceObject,
+ NextIrp,
+ IoGetCurrentIrpStackLocation( NextIrp ),
+ FALSE );
+ }
+
+ if( Status == STATUS_PENDING )
+ Status = STATUS_SUCCESS;
+ }
+
+ /* SocketStateUnlock( FCB ); */
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+
+ return Status;
+}
+
+/* Return the socket object for ths request only if it is a connected or
+ stream type. */
+NTSTATUS STDCALL
+AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp) {
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PAFD_CONNECT_INFO ConnectReq;
+ AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+ if( !(ConnectReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
+ 0, NULL, TRUE );
+
+ AFD_DbgPrint(MID_TRACE,("Connect request:\n"));
+ OskitDumpBuffer
+ ( (PCHAR)ConnectReq,
+ IrpSp->Parameters.DeviceIoControl.InputBufferLength );
+
+ switch( FCB->State ) {
+ case SOCKET_STATE_CONNECTED:
+ Status = STATUS_SUCCESS;
+ break;
+
+ case SOCKET_STATE_CONNECTING:
+ return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
+
+ case SOCKET_STATE_CREATED: {
+ FCB->LocalAddress =
+ TaCopyTransportAddress( &ConnectReq->RemoteAddress );
+
+ if( FCB->LocalAddress ) {
+ RtlZeroMemory( FCB->LocalAddress,
+ TaLengthOfTransportAddress
+ ( &ConnectReq->RemoteAddress ) );
+
+ FCB->LocalAddress->TAAddressCount = 1;
+ FCB->LocalAddress->Address[0].AddressType =
+ ConnectReq->RemoteAddress.Address[0].AddressType;
+ FCB->LocalAddress->Address[0].AddressLength =
+ ConnectReq->RemoteAddress.Address[0].AddressLength;
+
+ Status = WarmSocketForBind( FCB );
+
+ if( NT_SUCCESS(Status) )
+ FCB->State = SOCKET_STATE_BOUND;
+ else
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL,
+ TRUE );
+ } else
+ return UnlockAndMaybeComplete
+ ( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, TRUE );
+ } /* Drop through to SOCKET_STATE_BOUND */
+
+ case SOCKET_STATE_BOUND:
+ FCB->RemoteAddress =
+ TaCopyTransportAddress( &ConnectReq->RemoteAddress );
+
+ Status = WarmSocketForConnection( FCB );
+
+ FCB->State = SOCKET_STATE_CONNECTING;
+
+ if( NT_SUCCESS(Status) ) {
+ Status = TdiConnect( &FCB->PendingTdiIrp,
+ FCB->Connection.Object,
+ FCB->RemoteAddress,
+ StreamSocketConnectComplete,
+ FCB );
+ }
+ break;
+
+ default:
+ AFD_DbgPrint(MID_TRACE,("Inappropriate socket state %d for connect\n",
+ FCB->State));
+ break;
+ }
+
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
+}
reactos/drivers/net/afd/afd
diff -N context.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ context.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,68 @@
+/* $Id: context.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/context.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS STDCALL
+AfdGetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp ) {
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ UINT ContextSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+
+ if( FCB->ContextSize < ContextSize ) ContextSize = FCB->ContextSize;
+
+ if( FCB->Context ) {
+ RtlCopyMemory( Irp->UserBuffer,
+ FCB->Context,
+ ContextSize );
+ Status = STATUS_SUCCESS;
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
+}
+
+NTSTATUS STDCALL
+AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp ) {
+ NTSTATUS Status = STATUS_NO_MEMORY;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+
+ if( FCB->ContextSize <
+ IrpSp->Parameters.DeviceIoControl.InputBufferLength ) {
+ if( FCB->Context )
+ ExFreePool( FCB->Context );
+ FCB->Context =
+ ExAllocatePool
+ ( PagedPool,
+ IrpSp->Parameters.DeviceIoControl.InputBufferLength );
+ }
+
+ if( FCB->Context ) {
+ Status = STATUS_SUCCESS;
+ RtlCopyMemory( FCB->Context,
+ IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
+ IrpSp->Parameters.DeviceIoControl.InputBufferLength );
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
+}
reactos/drivers/net/afd/afd
diff -N info.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ info.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,52 @@
+/* $Id: info.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/info.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS STDCALL
+AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp ) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+
+ AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq,
+ InfoReq ? InfoReq->InformationClass : 0));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+
+ switch( InfoReq->InformationClass ) {
+ case AFD_INFO_RECEIVE_WINDOW_SIZE:
+ InfoReq->Information.Ulong = FCB->Recv.Size;
+ break;
+
+ case AFD_INFO_SEND_WINDOW_SIZE:
+ InfoReq->Information.Ulong = FCB->Send.Size;
+ AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size));
+ break;
+
+ case AFD_INFO_GROUP_ID_TYPE:
+ InfoReq->Information.Ulong = 0; /* What is group id */
+ break;
+
+ default:
+ AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
+ InfoReq->InformationClass));
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
+}
reactos/drivers/net/afd/afd
diff -N listen.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ listen.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,61 @@
+/* $Id: listen.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/listen.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS DDKAPI ListenComplete
+( PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context ) {
+ PAFD_FCB FCB = (PAFD_FCB)Context;
+ AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
+ AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", FCB->ListenIrp.Iosb.Status));
+ AFD_DbgPrint(MID_TRACE,("Doing nothing as yet.\n"));
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PAFD_LISTEN_DATA ListenReq;
+
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+ if( !(ListenReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
+ 0, NULL, FALSE );
+
+ if( FCB->State != SOCKET_STATE_BOUND ) {
+ Status = STATUS_UNSUCCESSFUL;
+ AFD_DbgPrint(MID_TRACE,("Could not listen an unbound socket\n"));
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
+ }
+
+ FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
+
+ Status = WarmSocketForConnection( FCB );
+
+ FCB->State = SOCKET_STATE_LISTENING;
+
+ Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
+ FCB->Connection.Object,
+ &FCB->ListenIrp.ConnectionInfo,
+ &FCB->ListenIrp.Iosb,
+ ListenComplete,
+ FCB );
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+ return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
+}
reactos/drivers/net/afd/afd
diff -N lock.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lock.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,212 @@
+/* $Id: lock.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/lock.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+/* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
+PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+ Irp->MdlAddress =
+ IoAllocateMdl( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
+ IrpSp->Parameters.DeviceIoControl.InputBufferLength,
+ FALSE,
+ FALSE,
+ NULL );
+ if( Irp->MdlAddress ) {
+ MmProbeAndLockPages( Irp->MdlAddress, KernelMode, IoModifyAccess );
+ IrpSp->Parameters.DeviceIoControl.Type3InputBuffer =
+ MmMapLockedPages( Irp->MdlAddress, KernelMode );
+ return IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ } else return NULL;
+}
+
+VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+ MmUnmapLockedPages( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
+ Irp->MdlAddress );
+ MmUnlockPages( Irp->MdlAddress );
+ IoFreeMdl( Irp->MdlAddress );
+ Irp->MdlAddress = NULL;
+}
+
+PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, BOOLEAN Write ) {
+ UINT i;
+ /* Copy the buffer array so we don't lose it */
+ UINT Size = sizeof(AFD_WSABUF) * Count;
+ 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 );
+
+ for( i = 0; i < Count; i++ ) {
+ AFD_DbgPrint(MID_TRACE,("Locking buffer %d (%x:%d)\n",
+ i, NewBuf[i].buf, NewBuf[i].len));
+
+ if( NewBuf[i].len ) {
+ NewMdl = IoAllocateMdl( NewBuf[i].buf,
+ NewBuf[i].len,
+ FALSE,
+ FALSE,
+ NULL );
+ } else {
+ MapBuf[i].Mdl = NULL;
+ continue;
+ }
+
+ AFD_DbgPrint(MID_TRACE,("NewMdl @ %x\n", NewMdl));
+
+ MapBuf[i].Mdl = NewMdl;
+
+ if( MapBuf[i].Mdl ) {
+ AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
+ MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
+ Write ? IoModifyAccess : IoReadAccess );
+ AFD_DbgPrint(MID_TRACE,("MmProbeAndLock finished\n"));
+ }
+ }
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Leaving %x\n", NewBuf));
+
+ return NewBuf;
+}
+
+VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count ) {
+ PAFD_MAPBUF Map = (PAFD_MAPBUF)(Buf + Count);
+ UINT i;
+
+ for( i = 0; i < Count; i++ ) {
+ if( Map[i].Mdl ) {
+ MmUnlockPages( Map[i].Mdl );
+ IoFreeMdl( Map[i].Mdl );
+ }
+ }
+
+ ExFreePool( Buf );
+}
+
+/* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
+UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID CurrentThread = KeGetCurrentThread();
+
+ AFD_DbgPrint(MAX_TRACE,("Called on %x, attempting to lock\n", FCB));
+
+ /* Wait for the previous user to unlock the FCB state. There might be
+ * multiple waiters waiting to change the state. We need to check each
+ * time we get the event whether somebody still has the state locked */
+
+ if( !FCB ) return FALSE;
+
+ if( CurrentThread == FCB->CurrentThread ) {
+ FCB->LockCount++;
+ AFD_DbgPrint(MID_TRACE,
+ ("Same thread, lock count %d\n", FCB->LockCount));
+ return TRUE;
+ } else {
+ AFD_DbgPrint(MID_TRACE,
+ ("Thread %x opposes lock thread %x\n",
+ CurrentThread, FCB->CurrentThread));
+ }
+
+ if( KeGetCurrentIrql() == PASSIVE_LEVEL ) {
+ ExAcquireFastMutex( &FCB->Mutex );
+ while( FCB->Locked ) {
+ AFD_DbgPrint
+ (MID_TRACE,("FCB %x is locked, waiting for notification\n",
+ FCB));
+ ExReleaseFastMutex( &FCB->Mutex );
+ Status = KeWaitForSingleObject( &FCB->StateLockedEvent,
+ UserRequest,
+ KernelMode,
+ FALSE,
+ NULL );
+ ExAcquireFastMutex( &FCB->Mutex );
+ if( Status == STATUS_SUCCESS ) break;
+ }
+ FCB->Locked = TRUE;
+ FCB->CurrentThread = CurrentThread;
+ FCB->LockCount++;
+ ExReleaseFastMutex( &FCB->Mutex );
+ } else {
+ KeAcquireSpinLock( &FCB->SpinLock, &FCB->OldIrql );
+ FCB->Locked = TRUE;
+ FCB->CurrentThread = CurrentThread;
+ FCB->LockCount++;
+ }
+ AFD_DbgPrint(MAX_TRACE,("Got lock (%d).\n", FCB->LockCount));
+
+ return TRUE;
+}
+
+VOID SocketStateUnlock( PAFD_FCB FCB ) {
+ ASSERT(FCB->LockCount > 0);
+ FCB->LockCount--;
+
+ if( !FCB->LockCount ) {
+ FCB->CurrentThread = NULL;
+ if( KeGetCurrentIrql() == PASSIVE_LEVEL ) {
+ ExAcquireFastMutex( &FCB->Mutex );
+ FCB->Locked = FALSE;
+ ExReleaseFastMutex( &FCB->Mutex );
+ } else {
+ FCB->Locked = FALSE;
+ KeReleaseSpinLock( &FCB->SpinLock, FCB->OldIrql );
+ }
+
+ AFD_DbgPrint(MAX_TRACE,("Unlocked.\n"));
+ KePulseEvent( &FCB->StateLockedEvent, IO_NETWORK_INCREMENT, FALSE );
+ } else {
+ AFD_DbgPrint(MID_TRACE,("Lock count %d\n", FCB->LockCount));
+ }
+}
+
+NTSTATUS DDKAPI UnlockAndMaybeComplete
+( PAFD_FCB FCB, NTSTATUS Status, PIRP Irp,
+ UINT Information,
+ PIO_COMPLETION_ROUTINE Completion,
+ BOOL ShouldUnlock ) {
+ SocketStateUnlock( FCB );
+ if( Status == STATUS_PENDING ) {
+ IoMarkIrpPending( Irp );
+ } else {
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = Information;
+ if( Completion )
+ Completion( FCB->DeviceExt->DeviceObject, Irp, FCB );
+ if( ShouldUnlock )
+ UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+ }
+ return Status;
+}
+
+
+NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp ) {
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+ AFD_DbgPrint(MIN_TRACE,("Called.\n"));
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = Status;
+ if( ShouldUnlockIrp )
+ UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
+ IoCompleteRequest( Irp, IO_NO_INCREMENT );
+ return Status;
+}
+
+NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
+ InsertTailList( &FCB->PendingIrpList[Function],
+ &Irp->Tail.Overlay.ListEntry );
+ return UnlockAndMaybeComplete( FCB, STATUS_PENDING, Irp, 0, NULL, FALSE );
+}
+
reactos/drivers/net/afd/afd
diff -N main.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ main.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,344 @@
+/* $Id: main.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/main.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040630 Created
+ *
+ * Suggestions: Uniform naming (AfdXxx)
+ */
+
+/* INCLUDES */
+
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+#ifdef DBG
+
+extern NTSTATUS DDKAPI MmCopyFromCaller( PVOID Dst, PVOID Src, UINT Size );
+
+/* See debug.h for debug/trace constants */
+DWORD DebugTraceLevel = DEBUG_ULTRA;
+
+#endif /* DBG */
+
+void OskitDumpBuffer( PCHAR Data, UINT Len ) {
+ unsigned int i;
+
+ for( i = 0; i < Len; i++ ) {
+ if( i && !(i & 0xf) ) DbgPrint( "\n" );
+ if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT)(Data + i) );
+ DbgPrint( " %02x", Data[i] & 0xff );
+ }
+ DbgPrint("\n");
+}
+
+/* FUNCTIONS */
+
+NTSTATUS STDCALL
+AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp) {
+ PAFD_FCB FCB;
+ PFILE_OBJECT FileObject;
+ PAFD_DEVICE_EXTENSION DeviceExt;
+ PFILE_FULL_EA_INFORMATION EaInfo;
+ PAFD_CREATE_PACKET ConnectInfo;
+ ULONG EaLength;
+ PWCHAR EaInfoValue;
+ UINT Disposition, i;
+
+ AFD_DbgPrint(MID_TRACE,
+ ("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
+
+ DeviceExt = DeviceObject->DeviceExtension;
+ FileObject = IrpSp->FileObject;
+ Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
+
+ Irp->IoStatus.Information = 0;
+
+ EaInfo = Irp->AssociatedIrp.SystemBuffer;
+ ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
+ EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
+
+ if(!EaInfo) {
+ AFD_DbgPrint(MIN_TRACE, ("No EA Info in IRP.\n"));
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ IoCompleteRequest( Irp, IO_NO_INCREMENT );
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
+ EaInfo->EaNameLength +
+ EaInfo->EaValueLength;
+
+ AFD_DbgPrint(MID_TRACE,("EaInfo: %x, EaInfoValue: %x\n",
+ EaInfo, EaInfoValue));
+
+ AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n"));
+
+ FCB = ExAllocatePool(NonPagedPool, sizeof(PAFD_FCB));
+ if( FCB == NULL ) {
+ Irp->IoStatus.Status = STATUS_NO_MEMORY;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NO_MEMORY;
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x)\n", FCB, FileObject));
+
+ RtlZeroMemory( FCB, sizeof( *FCB ) );
+
+ FCB->Flags = ConnectInfo->EndpointFlags;
+ FCB->State = SOCKET_STATE_CREATED;
+ FCB->FileObject = FileObject;
+ FCB->DeviceExt = DeviceExt;
+ FCB->Recv.Size = DEFAULT_RECEIVE_WINDOW_SIZE;
+ FCB->Send.Size = DEFAULT_SEND_WINDOW_SIZE;
+
+ KeInitializeSpinLock( &FCB->SpinLock );
+ ExInitializeFastMutex( &FCB->Mutex );
+ KeInitializeEvent( &FCB->StateLockedEvent, NotificationEvent, FALSE );
+
+ for( i = 0; i < MAX_FUNCTIONS; i++ ) {
+ InitializeListHead( &FCB->PendingIrpList[i] );
+ }
+
+ AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
+
+ FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
+ FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
+ FCB->TdiDeviceName.Buffer =
+ ExAllocatePool( NonPagedPool, FCB->TdiDeviceName.Length );
+ RtlCopyMemory( FCB->TdiDeviceName.Buffer,
+ ConnectInfo->TransportName,
+ FCB->TdiDeviceName.Length );
+
+ if( !FCB->TdiDeviceName.Buffer ) {
+ ExFreePool(FCB);
+ AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
+ Irp->IoStatus.Status = STATUS_NO_MEMORY;
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+ return STATUS_NO_MEMORY;
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Success: %s %wZ\n",
+ EaInfo->EaName, &FCB->TdiDeviceName));
+ FileObject->FsContext = FCB;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+{
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ UINT i;
+ PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
+
+ InFlightRequest[0] = &FCB->ListenIrp;
+ InFlightRequest[1] = &FCB->ReceiveIrp;
+ InFlightRequest[2] = &FCB->SendIrp;
+
+ AFD_DbgPrint(MID_TRACE,
+ ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
+
+ AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB));
+
+ FileObject->FsContext = NULL;
+ FCB->PollState |= AFD_EVENT_CLOSE;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ /* After PoolReeval, this FCB should not be involved in any outstanding
+ * poll requests */
+
+ /* Cancel our pending requests */
+ for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
+ NTSTATUS Status = STATUS_NO_SUCH_FILE;
+ if( InFlightRequest[i]->InFlightRequest ) {
+ InFlightRequest[i]->InFlightRequest->IoStatus.Status = Status;
+ InFlightRequest[i]->InFlightRequest->IoStatus.Information = 0;
+ IoCancelIrp( InFlightRequest[i]->InFlightRequest );
+ }
+ }
+
+ SocketStateUnlock( FCB );
+
+ if( FCB->Recv.Window )
+ ExFreePool( FCB->Recv.Window );
+ if( FCB->Send.Window )
+ ExFreePool( FCB->Send.Window );
+ if( FCB->AddressFrom )
+ ExFreePool( FCB->AddressFrom );
+ if( FCB->LocalAddress )
+ ExFreePool( FCB->LocalAddress );
+
+ ExFreePool(FCB->TdiDeviceName.Buffer);
+ ExFreePool(FCB);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+
+ AFD_DbgPrint(MID_TRACE,("AfdDispatch: %d\n", IrpSp->MajorFunction));
+ if( IrpSp->MajorFunction != IRP_MJ_CREATE) {
+ AFD_DbgPrint(MID_TRACE,("FO %x, IrpSp->FO %x\n",
+ FileObject, IrpSp->FileObject));
+ ASSERT(FileObject == IrpSp->FileObject);
+ }
+
+ switch(IrpSp->MajorFunction)
+ {
+ /* opening and closing handles to the device */
+ case IRP_MJ_CREATE:
+ /* Mostly borrowed from the named pipe file system */
+ return AfdCreateSocket(DeviceObject, Irp, IrpSp);
+
+ case IRP_MJ_CLOSE:
+ /* Ditto the borrowing */
+ return AfdCloseSocket(DeviceObject, Irp, IrpSp);
+
+ /* write data */
+ case IRP_MJ_WRITE:
+ return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp, TRUE );
+
+ /* read data */
+ case IRP_MJ_READ:
+ return AfdConnectedSocketReadData( DeviceObject, Irp, IrpSp, TRUE );
+
+ case IRP_MJ_DEVICE_CONTROL:
+ {
+ switch( IrpSp->Parameters.DeviceIoControl.IoControlCode ) {
+ case IOCTL_AFD_BIND:
+ return AfdBindSocket( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_CONNECT:
+ return AfdStreamSocketConnect( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_START_LISTEN:
+ return AfdListenSocket( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_RECV:
+ return AfdConnectedSocketReadData( DeviceObject, Irp, IrpSp,
+ FALSE );
+
+ case IOCTL_AFD_SELECT:
+ return AfdSelect( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_RECV_DATAGRAM:
+ return AfdPacketSocketReadData( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_SEND:
+ return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp,
+ FALSE );
+
+ case IOCTL_AFD_SEND_DATAGRAM:
+ return AfdPacketSocketWriteData( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_GET_INFO:
+ return AfdGetInfo( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_GET_CONTEXT:
+ return AfdGetContext( DeviceObject, Irp, IrpSp );
+
+ case IOCTL_AFD_SET_CONTEXT:
+ return AfdSetContext( DeviceObject, Irp, IrpSp );
+
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Information = 0;
+ AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%x)\n",
+ IrpSp->Parameters.DeviceIoControl.
+ IoControlCode));
+ break;
+ }
+ break;
+ }
+
+/* unsupported operations */
+ default:
+ {
+ Status = STATUS_NOT_IMPLEMENTED;
+ AFD_DbgPrint(MIN_TRACE,
+ ("Irp: Unknown Major code was %x\n",
+ IrpSp->MajorFunction));
+ break;
+ }
+ }
+
+ AFD_DbgPrint(MID_TRACE, ("Returning %x\n", Status));
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return (Status);
+}
+
+VOID STDCALL
+AfdUnload(PDRIVER_OBJECT DriverObject)
+{
+}
+
+NTSTATUS STDCALL
+DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+{
+ PDEVICE_OBJECT DeviceObject;
+ UNICODE_STRING wstrDeviceName;
+ PAFD_DEVICE_EXTENSION DeviceExt;
+ NTSTATUS Status;
+
+ /* register driver routines */
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdDispatch;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdDispatch;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdDispatch;
+ DriverObject->MajorFunction[IRP_MJ_READ] = AfdDispatch;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
+ DriverObject->DriverUnload = AfdUnload;
+
+ /* create afd device */
+ RtlRosInitUnicodeStringFromLiteral(&wstrDeviceName, L"\\Device\\Afd");
+
+ Status = IoCreateDevice
+ ( DriverObject,
+ sizeof(AFD_DEVICE_EXTENSION),
+ &wstrDeviceName,
+ FILE_DEVICE_NAMED_PIPE,
+ 0,
+ FALSE,
+ &DeviceObject );
+
+ /* failure */
+ if(!NT_SUCCESS(Status))
+ {
+ return (Status);
+ }
+
+ DeviceExt = DeviceObject->DeviceExtension;
+ KeInitializeSpinLock( &DeviceExt->Lock );
+ InitializeListHead( &DeviceExt->Polls );
+
+ AFD_DbgPrint(MID_TRACE,("Device created: object %x ext %x\n",
+ DeviceObject, DeviceExt));
+
+ return (Status);
+}
+
+/* EOF */
reactos/drivers/net/afd/afd
diff -N read.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ read.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,338 @@
+/* $Id: read.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/read.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ *
+ * Improve buffering code
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
+ PAFD_RECV_INFO RecvReq,
+ PUINT TotalBytesCopied ) {
+ UINT i, BytesToCopy = 0,
+ BytesAvailable =
+ FCB->Recv.Content - FCB->Recv.BytesUsed;
+ *TotalBytesCopied = 0;
+ PAFD_MAPBUF Map;
+
+ if( !BytesAvailable ) return STATUS_PENDING;
+
+ Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
+
+ AFD_DbgPrint(MID_TRACE,("Buffer Count: %d @ %x\n",
+ RecvReq->BufferCount,
+ RecvReq->BufferArray));
+ for( i = 0;
+ RecvReq->BufferArray &&
+ BytesAvailable &&
+ i < RecvReq->BufferCount;
+ i++ ) {
+ BytesToCopy =
+ MIN( RecvReq->BufferArray[i].len, BytesAvailable );
+
+ if( Map[i].Mdl ) {
+ Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode );
+
+ AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
+ i,
+ Map[i].BufferAddress,
+ BytesToCopy));
+ RtlCopyMemory( Map[i].BufferAddress,
+ FCB->Recv.Window + FCB->Recv.BytesUsed,
+ BytesToCopy );
+
+ MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl );
+
+ FCB->Recv.BytesUsed += BytesToCopy;
+ *TotalBytesCopied += BytesToCopy;
+ BytesAvailable -= BytesToCopy;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS DDKAPI ReceiveComplete
+( PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context ) {
+ NTSTATUS Status = Irp->IoStatus.Status;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ PAFD_FCB FCB = (PAFD_FCB)Context;
+ PLIST_ENTRY NextIrpEntry;
+ PIRP NextIrp;
+ PIO_STACK_LOCATION NextIrpSp;
+ PAFD_RECV_INFO RecvReq;
+ UINT TotalBytesCopied = 0;
+
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ if( !SocketAcquireStateLock( FCB ) ) return Status;
+
+ if( NT_SUCCESS(Irp->IoStatus.Status) ) {
+ /* Update the receive window */
+ FCB->Recv.Content = Irp->IoStatus.Information;
+ FCB->Recv.BytesUsed = 0;
+ /* Kick the user that receive would be possible now */
+ /* XXX Not implemented yet */
+
+ AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n",
+ FCB, FCB->Recv.Content));
+ OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );
+
+ Status = STATUS_SUCCESS;
+
+ /* Try to clear some requests */
+ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) &&
+ NT_SUCCESS(Status) ) {
+ NextIrpEntry =
+ RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
+ NextIrp =
+ CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+ NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
+ RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+
+ AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq));
+
+ Status = TryToSatisfyRecvRequestFromBuffer
+ ( FCB, RecvReq, &TotalBytesCopied );
+
+ if( Status == STATUS_PENDING ) {
+ AFD_DbgPrint(MID_TRACE,("Ran out of data for %x\n", NextIrp));
+ InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV],
+ &NextIrp->Tail.Overlay.ListEntry);
+ break;
+ } else {
+ AFD_DbgPrint(MID_TRACE,("Completing recv %x\n", NextIrp));
+ UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
+ NextIrp->IoStatus.Status = Status;
+ NextIrp->IoStatus.Information = TotalBytesCopied;
+ IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+ }
+ }
+
+ if( FCB->Recv.Window && !FCB->Recv.Content ) {
+ AFD_DbgPrint(MID_TRACE,
+ ("Exhausted our buffer. Requesting new: %x\n", FCB));
+
+ Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
+ IrpSp->FileObject,
+ TDI_RECEIVE_NORMAL,
+ FCB->Recv.Window,
+ FCB->Recv.Size,
+ &FCB->ReceiveIrp.Iosb,
+ ReceiveComplete,
+ FCB );
+ }
+ } else {
+ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
+ NextIrpEntry =
+ RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
+ NextIrp =
+ CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+ AFD_DbgPrint(MID_TRACE,("Completing recv %x (%x)\n",
+ NextIrp, Status));
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+ }
+ }
+
+ if( FCB->Recv.Content ) {
+ FCB->PollState |= AFD_EVENT_RECEIVE;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ } else
+ FCB->PollState &= ~AFD_EVENT_RECEIVE;
+
+
+ SocketStateUnlock( FCB );
+
+ AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));
+
+ return Status;
+}
+
+NTSTATUS STDCALL
+AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp, BOOLEAN Short) {
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PAFD_RECV_INFO RecvReq;
+ UINT TotalBytesCopied = 0;
+
+ AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
+ if( !(RecvReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
+ Irp, 0, NULL, FALSE );
+
+ RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
+ RecvReq->BufferCount,
+ TRUE );
+
+ Status = TryToSatisfyRecvRequestFromBuffer
+ ( FCB, RecvReq, &TotalBytesCopied );
+
+ if( Status != STATUS_PENDING ) {
+ UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
+ return UnlockAndMaybeComplete( FCB, Status, Irp,
+ TotalBytesCopied, NULL, TRUE );
+ } else {
+ return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
+ }
+}
+
+
+NTSTATUS STDCALL
+SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
+ PAFD_STORED_DATAGRAM DatagramRecv ) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
+ PAFD_RECV_INFO RecvReq =
+ IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ UINT CopyLen = 0;
+
+ CopyLen = MIN(DatagramRecv->Len, RecvReq->BufferArray[0].len);
+ RtlCopyMemory( RecvReq->BufferArray[0].buf, DatagramRecv->Buffer,
+ CopyLen );
+
+ Status = Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = CopyLen;
+ ExFreePool( DatagramRecv );
+
+ return Status;
+}
+
+NTSTATUS DDKAPI
+PacketSocketRecvComplete(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context ) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAFD_FCB FCB = Context;
+ PIRP NextIrp;
+ 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 ) ) {
+ SocketStateUnlock( FCB );
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
+
+ if( DatagramRecv ) {
+ DatagramRecv->Len = Irp->IoStatus.Information;
+ RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
+ DatagramRecv->Len );
+ 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_DATAGRAM] ) ) {
+ ListEntry = RemoveHeadList( &FCB->DatagramList );
+ DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
+ ListEntry );
+ ListEntry = RemoveHeadList
+ ( &FCB->PendingIrpList[FUNCTION_RECV_DATAGRAM] );
+ NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
+ RecvReq = NextIrp->AssociatedIrp.SystemBuffer;
+
+ 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 );
+ IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+ } else {
+ Status = SatisfyPacketRecvRequest( FCB, NextIrp, DatagramRecv );
+ UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount );
+ IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+ }
+ }
+
+ if( !IsListEmpty( &FCB->DatagramList ) ) {
+ FCB->PollState |= AFD_EVENT_RECEIVE;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ }
+
+ /* Now relaunch the datagram request */
+ Status = TdiReceiveDatagram
+ ( &FCB->ReceiveIrp.InFlightRequest,
+ FCB->AddressFile.Object,
+ 0,
+ FCB->Recv.Window,
+ FCB->Recv.Size,
+ FCB->AddressFrom,
+ &FCB->ReceiveIrp.Iosb,
+ PacketSocketRecvComplete,
+ 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 RecvReq;
+ PLIST_ENTRY ListEntry;
+ PAFD_STORED_DATAGRAM DatagramRecv;
+
+ AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
+ if( !(RecvReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
+ Irp, 0, NULL, FALSE );
+
+ 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;
+ return UnlockAndMaybeComplete
+ ( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
+ } else {
+ if( IsListEmpty( &FCB->DatagramList ) )
+ FCB->PollState &= ~AFD_EVENT_RECEIVE;
+
+ Status = SatisfyPacketRecvRequest( FCB, Irp, DatagramRecv );
+ return UnlockAndMaybeComplete
+ ( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
+ }
+ } else {
+ RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray,
+ RecvReq->BufferCount,
+ TRUE );
+ return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV_DATAGRAM );
+ }
+}
reactos/drivers/net/afd/afd
diff -N select.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ select.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,237 @@
+/* $Id: select.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/select.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+VOID CopyBackStatus( PAFD_HANDLE HandleArray,
+ UINT HandleCount ) {
+ UINT i;
+
+ for( i = 0; i < HandleCount; i++ ) {
+ HandleArray[i].Events = HandleArray[i].Status;
+ HandleArray[i].Status = 0;
+ }
+}
+
+VOID ZeroEvents( PAFD_HANDLE HandleArray,
+ UINT HandleCount ) {
+ UINT i;
+
+ for( i = 0; i < HandleCount; i++ ) {
+ HandleArray[i].Events = 0;
+ HandleArray[i].Status = 0;
+ }
+}
+
+NTSTATUS STDCALL
+ScanForImmediateTrigger( PAFD_HANDLE HandleArray,
+ UINT HandleCount,
+ PUINT HandlesSet ) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_OBJECT FileObject;
+ PAFD_FCB FCB;
+ UINT i;
+ BOOLEAN ShouldReturnNow = FALSE;
+
+ for( i = 0; i < HandleCount && NT_SUCCESS(Status); i++ ) {
+ HandleArray[i].Status = 0;
+ Status =
+ ObReferenceObjectByHandle
+ ( (PVOID)HandleArray[i].Handle,
+ FILE_ALL_ACCESS,
+ NULL,
+ KernelMode,
+ (PVOID*)&FileObject,
+ NULL );
+
+ if( NT_SUCCESS(Status) ) {
+ FCB = FileObject->FsContext;
+ /* Check select bits */
+ if( !SocketAcquireStateLock( FCB ) )
+ Status = STATUS_UNSUCCESSFUL;
+ if( NT_SUCCESS(Status) )
+ HandleArray[i].Status =
+ FCB->PollState & HandleArray[i].Events;
+ if( HandleArray[i].Status ) ShouldReturnNow = TRUE;
+ ObDereferenceObject( (PVOID)HandleArray[i].Handle );
+ }
+ }
+
+ if( !NT_SUCCESS(Status) || ShouldReturnNow ) return Status;
+ else return STATUS_PENDING;
+}
+
+VOID SelectTimeout( PKDPC Dpc,
+ PVOID DeferredContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2 ) {
+ PAFD_ACTIVE_POLL Poll = DeferredContext;
+ PAFD_POLL_INFO PollReq;
+ PAFD_DEVICE_EXTENSION DeviceExt;
+ PIRP Irp;
+ KIRQL OldIrql;
+
+ Irp = Poll->Irp;
+ DeviceExt = Poll->DeviceExt;
+
+ PollReq = Irp->AssociatedIrp.SystemBuffer;
+
+ KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+ RemoveEntryList( &Poll->ListEntry );
+ KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
+
+ ExFreePool( Poll );
+
+ ZeroEvents( PollReq->Handles, PollReq->HandleCount );
+
+ Irp->IoStatus.Status = STATUS_TIMEOUT;
+ Irp->IoStatus.Information = -1;
+
+ IoCompleteRequest( Irp, IO_NO_INCREMENT );
+}
+
+NTSTATUS STDCALL
+AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp ) {
+ NTSTATUS Status = STATUS_NO_MEMORY;
+ PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer;
+ PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
+ PAFD_ACTIVE_POLL Poll = NULL;
+ UINT CopySize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ UINT AllocSize =
+ CopySize + sizeof(AFD_ACTIVE_POLL) - sizeof(AFD_POLL_INFO);
+ KIRQL OldIrql;
+ UINT HandlesSignalled;
+
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ Status = ScanForImmediateTrigger( PollReq->Handles,
+ PollReq->HandleCount,
+ &HandlesSignalled );
+
+ if( Status == STATUS_PENDING ) {
+ Poll = ExAllocatePool( NonPagedPool, AllocSize );
+
+ if( Poll ) {
+ KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+
+ KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
+ (PKDEFERRED_ROUTINE)SelectTimeout,
+ Poll );
+ PollReq->Timeout.QuadPart *= -1;
+ /* Negative values are relative */
+ KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
+ KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
+
+ Poll->Irp = Irp;
+ Poll->DeviceExt = DeviceExt;
+
+ InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
+ Status = STATUS_PENDING;
+
+ KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
+ } else Status = STATUS_NO_MEMORY;
+ } else if( Status == STATUS_SUCCESS ) {
+ CopyBackStatus( PollReq->Handles,
+ PollReq->HandleCount );
+ } else {
+ ZeroEvents( PollReq->Handles,
+ PollReq->HandleCount );
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+
+ if( Status == STATUS_PENDING )
+ IoMarkIrpPending( Irp );
+ else {
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = HandlesSignalled;
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+ }
+
+ return Status;
+}
+
+VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq, UINT i ) {
+ /* One of the files was destroyed. We return now with error. */
+ Poll->Irp->IoStatus.Status = STATUS_SUCCESS; /* XXX REVISIT */
+ Poll->Irp->IoStatus.Information = 1;
+ CopyBackStatus( PollReq->Handles,
+ PollReq->HandleCount );
+ IoCompleteRequest( Poll->Irp, IO_NETWORK_INCREMENT );
+}
+
+BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
+ UINT i;
+ NTSTATUS Status;
+ PFILE_OBJECT TargetFile;
+ PAFD_FCB FCB;
+ PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
+
+ for( i = 0; i < PollReq->HandleCount; i++ ) {
+ Status =
+ ObReferenceObjectByHandle
+ ( (PVOID)PollReq->Handles[i].Handle,
+ FILE_ALL_ACCESS,
+ NULL,
+ KernelMode,
+ (PVOID*)&TargetFile,
+ NULL );
+
+ if( !NT_SUCCESS(Status) ) {
+ PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
+ SignalSocket( Poll, PollReq, i );
+ return TRUE;
+ } else {
+ FCB = FileObject->FsContext;
+
+ if( !SocketAcquireStateLock( FCB ) ) {
+ PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
+ SignalSocket( Poll, PollReq, i );
+ } else {
+ PollReq->Handles[i].Status =
+ PollReq->Handles[i].Events & FCB->PollState;
+ if( PollReq->Handles[i].Status )
+ SignalSocket( Poll, PollReq, i );
+ }
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
+ PAFD_ACTIVE_POLL Poll = NULL;
+ PLIST_ENTRY ThePollEnt = NULL;
+ KIRQL OldIrql;
+
+ AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n",
+ DeviceExt, FileObject));
+
+ KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+
+ ThePollEnt = DeviceExt->Polls.Flink;
+
+ while( ThePollEnt != &DeviceExt->Polls ) {
+ Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
+ if( UpdatePollWithFCB( Poll, FileObject ) ) {
+ ThePollEnt = ThePollEnt->Flink;
+ RemoveEntryList( &Poll->ListEntry );
+ } else
+ ThePollEnt = ThePollEnt->Flink;
+ }
+
+ KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
+
+ AFD_DbgPrint(MID_TRACE,("Leaving"));
+}
reactos/drivers/net/afd/afd
diff -N write.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ write.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,269 @@
+/* $Id: write.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/write.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
+#include "afd.h"
+#include "tdi_proto.h"
+#include "tdiconn.h"
+#include "debug.h"
+
+NTSTATUS DDKAPI SendComplete
+( PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context ) {
+ NTSTATUS Status = Irp->IoStatus.Status;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ PAFD_FCB FCB = (PAFD_FCB)Context;
+ PLIST_ENTRY NextIrpEntry;
+ PIRP NextIrp = NULL;
+ PIO_STACK_LOCATION NextIrpSp;
+ PAFD_SEND_INFO SendReq;
+ PAFD_MAPBUF Map;
+ UINT TotalBytesCopied = 0, SpaceAvail, i, CopySize = 0;
+
+ AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n",
+ Irp->IoStatus.Status,
+ Irp->IoStatus.Information));
+
+ if( !SocketAcquireStateLock( FCB ) ) return Status;
+
+ if( !NT_SUCCESS(Status) ) {
+ /* Complete all following send IRPs with error */
+
+ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
+ NextIrpEntry =
+ RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
+ NextIrp =
+ CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+ NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
+ SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+
+ UnlockBuffers( SendReq->BufferArray,
+ SendReq->BufferCount );
+
+ NextIrp->IoStatus.Status = Status;
+ NextIrp->IoStatus.Information = 0;
+
+ IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+ }
+
+ SocketStateUnlock( FCB );
+ return STATUS_SUCCESS;
+ }
+
+ RtlMoveMemory( FCB->Send.Window,
+ FCB->Send.Window + FCB->Send.BytesUsed,
+ FCB->Send.BytesUsed - Irp->IoStatus.Information );
+ FCB->Send.BytesUsed -= Irp->IoStatus.Information;
+
+ if( !FCB->Send.BytesUsed &&
+ !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) &&
+ NT_SUCCESS(Status) ) {
+ NextIrpEntry =
+ RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
+ NextIrp =
+ CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+ NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
+ SendReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
+
+ AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq));
+
+ SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
+
+ for( i = 0; FCB->Send.BytesUsed < FCB->Send.Content &&
+ i < SendReq->BufferCount; i++ ) {
+ Map[i].BufferAddress =
+ MmMapLockedPages( Map[i].Mdl, KernelMode );
+
+ CopySize = MIN( SpaceAvail,
+ SendReq->BufferArray[i].len );
+
+ RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
+ Map[i].BufferAddress,
+ CopySize );
+
+ MmUnmapLockedPages( Map[i].Mdl, KernelMode );
+
+ FCB->Send.BytesUsed += CopySize;
+ TotalBytesCopied += CopySize;
+ SpaceAvail -= CopySize;
+ }
+ }
+
+ /* Some data is still waiting */
+ if( FCB->Send.BytesUsed ) {
+ FCB->PollState &= ~AFD_EVENT_SEND;
+ Status = TdiSend( &FCB->SendIrp.InFlightRequest,
+ IrpSp->FileObject,
+ 0,
+ FCB->Send.Window,
+ FCB->Send.BytesUsed,
+ &FCB->SendIrp.Iosb,
+ SendComplete,
+ FCB );
+ } else {
+ FCB->PollState |= AFD_EVENT_SEND;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ }
+
+ if( TotalBytesCopied > 0 ) {
+ UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
+
+ if( Status == STATUS_PENDING )
+ Status = STATUS_SUCCESS;
+
+ AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
+
+ return UnlockAndMaybeComplete( FCB, Status, Irp, TotalBytesCopied,
+ NULL, TRUE );
+ } else if( NextIrp ) {
+ AFD_DbgPrint(MID_TRACE,("Could not do any more with Irp %x\n",
+ NextIrp));
+ InsertHeadList( &FCB->PendingIrpList[FUNCTION_SEND],
+ &Irp->Tail.Overlay.ListEntry );
+
+ SocketStateUnlock( FCB );
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp, BOOLEAN Short) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PAFD_SEND_INFO SendReq;
+ UINT TotalBytesCopied = 0, i, CopySize = 0,
+ SpaceAvail = 0, TotalBytesEncountered = 0;
+
+ AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
+ if( !(SendReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete
+ ( FCB, STATUS_NO_MEMORY, Irp, TotalBytesCopied, NULL, FALSE );
+
+ 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 );
+ }
+
+ AFD_DbgPrint(MID_TRACE,("We already have %d bytes waiting.\n",
+ FCB->Send.BytesUsed));
+
+ SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
+ SendReq->BufferCount,
+ FALSE );
+
+ AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n",
+ FCB->Send.BytesUsed));
+
+ if( !FCB->Send.BytesUsed ) {
+ SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
+
+ AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
+ SpaceAvail));
+
+ for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
+ i < SendReq->BufferCount; i++ ) {
+ CopySize = MIN( SpaceAvail,
+ SendReq->BufferArray[i].len );
+
+ TotalBytesEncountered += SendReq->BufferArray[i].len;
+
+ AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n",
+ i,
+ SendReq->BufferArray[i].buf,
+ CopySize,
+ FCB->Send.Window + FCB->Send.BytesUsed));
+
+ RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
+ SendReq->BufferArray[i].buf,
+ CopySize );
+
+ FCB->Send.BytesUsed += CopySize;
+ TotalBytesCopied += CopySize;
+ SpaceAvail -= CopySize;
+ }
+
+ if( TotalBytesEncountered == 0 ) {
+ UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
+
+ AFD_DbgPrint(MID_TRACE,("Empty send\n"));
+ return UnlockAndMaybeComplete
+ ( FCB, Status, Irp, TotalBytesCopied, NULL, TRUE );
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Completed %d bytes\n", TotalBytesCopied));
+
+ if( TotalBytesCopied > 0 ) {
+ UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
+
+ Status = TdiSend( &FCB->SendIrp.InFlightRequest,
+ FCB->Connection.Object,
+ 0,
+ FCB->Send.Window,
+ FCB->Send.BytesUsed,
+ &FCB->SendIrp.Iosb,
+ SendComplete,
+ FCB );
+
+ if( Status == STATUS_PENDING )
+ Status = STATUS_SUCCESS;
+
+ AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
+
+ return UnlockAndMaybeComplete
+ ( FCB, Status, Irp, TotalBytesCopied, NULL, TRUE );
+ }
+ }
+
+ AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
+ return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
+}
+
+NTSTATUS STDCALL
+AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp) {
+ NTSTATUS Status = STATUS_SUCCESS;
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PAFD_SEND_INFO_UDP SendReq;
+
+ AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+
+ if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
+ if( !(SendReq = LockRequest( Irp, IrpSp )) )
+ return UnlockAndMaybeComplete
+ ( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );
+
+ /* Check the size of the Address given ... */
+
+ Status = TdiSendDatagram
+ ( &FCB->SendIrp.InFlightRequest,
+ FCB->AddressFile.Object,
+ SendReq->BufferArray[0].buf,
+ SendReq->BufferArray[0].len,
+ SendReq->RemoteAddress,
+ &FCB->SendIrp.Iosb,
+ NULL,
+ NULL );
+
+ if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
+
+ AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
+
+ return UnlockAndMaybeComplete
+ ( FCB, Status, Irp, SendReq->BufferArray[0].len, NULL, TRUE );
+}
+
reactos/drivers/net/afd/afd
diff -u -r1.13 -r1.14
--- tdi.c 3 Jul 2004 17:40:20 -0000 1.13
+++ tdi.c 18 Jul 2004 22:49:17 -0000 1.14
@@ -8,6 +8,7 @@
* CSH 01/09-2000 Created
*/
#include <afd.h>
+#include "debug.h"
#include "tdiconn.h"
#ifdef DBG
@@ -57,10 +58,12 @@
{
NTSTATUS Status;
- AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+ AFD_DbgPrint(MID_TRACE, ("Called\n"));
+
+ AFD_DbgPrint(MID_TRACE, ("Irp->UserEvent = %x\n", Irp->UserEvent));
Status = IoCallDriver(DeviceObject, Irp);
- AFD_DbgPrint(MAX_TRACE, ("IoCallDriver: %08x\n", Status));
+ AFD_DbgPrint(MID_TRACE, ("IoCallDriver: %08x\n", Status));
if ((Status == STATUS_PENDING) && (Event != NULL)) {
AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
@@ -110,7 +113,7 @@
NULL); /* Security descriptor */
Status = ZwCreateFile(Handle, /* Return file handle */
- GENERIC_READ | GENERIC_WRITE, /* Desired access */
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, /* Desired access */
&Attr, /* Object attributes */
&Iosb, /* IO status */
0, /* Initial allocation size */
@@ -122,7 +125,7 @@
EaLength); /* EA length */
if (NT_SUCCESS(Status)) {
Status = ObReferenceObjectByHandle(*Handle, /* Handle to open file */
- GENERIC_READ | GENERIC_WRITE, /* Access mode */
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, /* Access mode */
NULL, /* Object type */
KernelMode, /* Access mode */
(PVOID*)Object, /* Pointer to object */
@@ -158,9 +161,9 @@
}
-NTSTATUS TdiOpenAddressFileIPv4(
+NTSTATUS TdiOpenAddressFile(
PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
+ PTRANSPORT_ADDRESS Name,
PHANDLE AddressHandle,
PFILE_OBJECT *AddressObject)
/*
@@ -175,21 +178,21 @@
*/
{
PFILE_FULL_EA_INFORMATION EaInfo;
- PTA_IP_ADDRESS Address;
NTSTATUS Status;
ULONG EaLength;
-
+ PTRANSPORT_ADDRESS Address;
+
AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (0x%X)\n",
- DeviceName, Name));
-
- /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
+ DeviceName, Name));
+
+ /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
- TDI_TRANSPORT_ADDRESS_LENGTH +
- sizeof(TA_IP_ADDRESS) + 1;
+ TDI_TRANSPORT_ADDRESS_LENGTH +
+ TaLengthOfTransportAddress( Name ) + 1;
EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
if (!EaInfo)
- return STATUS_INSUFFICIENT_RESOURCES;
-
+ return STATUS_INSUFFICIENT_RESOURCES;
+
RtlZeroMemory(EaInfo, EaLength);
EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
/* Don't copy the terminating 0; we have already zeroed it */
@@ -197,9 +200,9 @@
TdiTransportAddress,
TDI_TRANSPORT_ADDRESS_LENGTH);
EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS);
- Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */
- TdiBuildAddressIPv4(Address, Name);
-
+ Address =
+ (PTRANSPORT_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */
+ TaCopyTransportAddressInPlace( Address, Name );
Status = TdiOpenDevice(DeviceName,
EaLength,
EaInfo,
@@ -210,43 +213,6 @@
}
-NTSTATUS TdiOpenAddressFile(
- PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
- PHANDLE AddressHandle,
- PFILE_OBJECT *AddressObject)
-/*
- * FUNCTION: Opens an address file object
- * ARGUMENTS:
- * DeviceName = Pointer to counted string with name of device
- * Name = Pointer to socket name
- * AddressHandle = Address of buffer to place address file handle
- * AddressObject = Address of buffer to place address file object
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
-
- switch (Name->sa_family) {
- case AF_INET:
- Status = TdiOpenAddressFileIPv4(
- DeviceName,
- Name,
- AddressHandle,
- AddressObject);
- break;
-
- default:
- AFD_DbgPrint(MAX_TRACE, ("Unknown socket address family (0x%X)\n",
- Name->sa_family));
- Status = STATUS_INVALID_PARAMETER;
- }
-
- return Status;
-}
-
-
NTSTATUS TdiOpenConnectionEndpointFile(
PUNICODE_STRING DeviceName,
PHANDLE ConnectionHandle,
@@ -298,8 +264,11 @@
NTSTATUS TdiConnect(
- PFILE_OBJECT ConnectionObject,
- LPSOCKADDR RemoteAddress)
+ PIRP *Irp,
+ PFILE_OBJECT ConnectionObject,
+ PTRANSPORT_ADDRESS RemoteAddress,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext)
/*
* FUNCTION: Connect a connection endpoint to a remote peer
* ARGUMENTS:
@@ -315,7 +284,6 @@
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
- PIRP Irp;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
@@ -323,12 +291,17 @@
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
- Status = TdiBuildConnectionInfo(&RequestConnectionInfo, RemoteAddress);
- if (!NT_SUCCESS(Status))
+ /* Use same TDI address type for return connection information */
+ Status = TdiBuildConnectionInfo(&RequestConnectionInfo,
+ &RemoteAddress->Address[0]);
+ if (!NT_SUCCESS(Status)) {
+ ExFreePool(RequestConnectionInfo);
return Status;
+ }
/* Use same TDI address type for return connection information */
- Status = TdiBuildConnectionInfo(&ReturnConnectionInfo, RemoteAddress);
+ Status = TdiBuildConnectionInfo(&ReturnConnectionInfo,
+ &RemoteAddress->Address[0]);
if (!NT_SUCCESS(Status)) {
ExFreePool(RequestConnectionInfo);
ExFreePool(ReturnConnectionInfo);
@@ -337,29 +310,27 @@
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, /* Sub function */
- DeviceObject, /* Device object */
- ConnectionObject, /* File object */
- &Event, /* Event */
- &Iosb); /* Status */
- if (!Irp) {
- ExFreePool(RequestConnectionInfo);
+ *Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, /* Sub function */
+ DeviceObject, /* Device object */
+ ConnectionObject, /* File object */
+ &Event, /* Event */
+ &Iosb); /* Status */
+ if (!*Irp) {
ExFreePool(ReturnConnectionInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
- TdiBuildConnect(Irp, /* IRP */
+ TdiBuildConnect(*Irp, /* IRP */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
- NULL, /* Completion routine */
- NULL, /* Completion routine context */
+ CompletionRoutine, /* Completion routine */
+ CompletionContext, /* Completion routine context */
NULL, /* Time */
RequestConnectionInfo, /* Request connection information */
ReturnConnectionInfo); /* Return connection information */
- Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
+ Status = TdiCall(*Irp, DeviceObject, &Event, &Iosb);
- ExFreePool(RequestConnectionInfo);
ExFreePool(ReturnConnectionInfo);
return Status;
@@ -414,14 +385,16 @@
}
-NTSTATUS TdiListen(
- PAFD_LISTEN_REQUEST ListenRequest,
+NTSTATUS TdiListen
+( PIRP *Irp,
+ PFILE_OBJECT ConnectionObject,
+ PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
+ PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
* FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
* ARGUMENTS:
- * ListenRequest = Pointer to listen request object
* CompletionRoutine = Routine to be called when IRP is completed
* CompletionContext = Context for CompletionRoutine
* RETURNS:
@@ -429,46 +402,40 @@
* May return STATUS_PENDING
*/
{
- PFILE_OBJECT ConnectionObject;
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
- PIRP Irp;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
- ConnectionObject = ListenRequest->Fcb->TdiConnectionObject;
- assert(ConnectionObject);
-
DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
- Status = TdiBuildNullConnectionInfo(&ListenRequest->RequestConnectionInfo,
- TDI_ADDRESS_TYPE_IP);
+ Status = TdiBuildNullConnectionInfo(RequestConnectionInfo,
+ TDI_ADDRESS_TYPE_IP);
if (!NT_SUCCESS(Status))
return Status;
- Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
- DeviceObject, /* Device object */
- ConnectionObject, /* File object */
- NULL, /* Event */
- &ListenRequest->Iosb); /* Status */
- if (Irp == NULL)
+ *Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
+ DeviceObject, /* Device object */
+ ConnectionObject, /* File object */
+ NULL, /* Event */
+ Iosb); /* Status */
+ if (*Irp == NULL)
{
- ExFreePool(ListenRequest->RequestConnectionInfo);
- ListenRequest->RequestConnectionInfo = NULL;
- return STATUS_INSUFFICIENT_RESOURCES;
+ ExFreePool(*RequestConnectionInfo);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
-
- TdiBuildListen(Irp, /* IRP */
+
+ TdiBuildListen(*Irp, /* IRP */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
CompletionRoutine, /* Completion routine */
CompletionContext, /* Completion routine context */
0, /* Flags */
- ListenRequest->RequestConnectionInfo, /* Request connection information */
+ *RequestConnectionInfo, /* Request connection information */
NULL /* ReturnConnectionInfo */); /* Return connection information */
- Status = TdiCall(Irp, DeviceObject, NULL /* Don't wait for completion */, &ListenRequest->Iosb);
-
+ Status = TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
+
return Status;
}
@@ -629,7 +596,7 @@
return Status;
}
-
+#if 0
NTSTATUS TdiQueryInformationEx(
PFILE_OBJECT FileObject,
ULONG Entity,
@@ -672,7 +639,6 @@
OutputLength); /* Return information */
}
-
NTSTATUS TdiQueryAddress(
PFILE_OBJECT FileObject,
PULONG Address)
@@ -806,31 +772,20 @@
return Status;
}
+#endif
-
-NTSTATUS TdiSend(
- PFILE_OBJECT TransportObject,
- PVOID Buffer,
- ULONG BufferSize)
-/*
- * FUNCTION: Sends a block of data
- * ARGUMENTS:
- * TransportObject = Pointer to transport object
- * Buffer = Pointer to buffer with data to send
- * BufferSize = Length of Buffer
- * RETURNS:
- * Status of operation
- */
+NTSTATUS TdiSend
+( PIRP *Irp,
+ PFILE_OBJECT TransportObject,
+ USHORT Flags,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext )
{
-#if 0
- PTDI_CONNECTION_INFORMATION ConnectInfo;
PDEVICE_OBJECT DeviceObject;
- IO_STATUS_BLOCK Iosb;
- DWORD TdiAddressSize;
- PVOID BaseAddress;
NTSTATUS Status;
- KEVENT Event;
- PIRP Irp;
PMDL Mdl;
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
@@ -839,38 +794,28 @@
return STATUS_INVALID_PARAMETER;
}
- Status = TdiBuildConnectionInfo( &ConnectInfo, Address );
- if (!NT_SUCCESS(Status))
- return STATUS_INSUFFICIENT_RESOURCES;
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ *Irp = TdiBuildInternalDeviceControlIrp
+ ( TDI_SEND, /* Sub function */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ NULL, /* Event */
+ Iosb ); /* Status */
- Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
- DeviceObject, /* Device object */
- TransportObject, /* File object */
- &Event, /* Event */
- &Iosb); /* Status */
- if (!Irp) {
- AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
- ExFreePool(ConnectInfo);
+ if (!*Irp) {
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
-DisplayBuffer(Request->Buffers->buf, Request->Buffers->len);
-
+ AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));
- /* FIXME: There may be more than one buffer */
- BufferSize = Request->Buffers->len;
- Mdl = IoAllocateMdl(
- Request->Buffers->buf, /* Virtual address of buffer */
- Request->Buffers->len, /* Length of buffer */
- FALSE, /* Not secondary */
- FALSE, /* Don't charge quota */
- NULL); /* Don't use IRP */
+ Mdl = IoAllocateMdl(Buffer, /* Virtual address */
+ BufferLength, /* Length of buffer */
+ FALSE, /* Not secondary */
+ FALSE, /* Don't charge quota */
+ *Irp); /* use IRP */
if (!Mdl) {
- AFD_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
- IoFreeIrp(Irp);
- ExFreePool(ConnectInfo);
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ IoFreeIrp(*Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
@@ -879,68 +824,133 @@
#endif
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
#ifdef _MSC_VER
- } except(EXCEPTION_EXECUTE_HANDLER) {
+ } except (EXCEPTION_EXECUTE_HANDLER) {
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
- IoFreeMdl(Mdl);
- IoFreeIrp(Irp);
- ExFreePool(ConnectInfo);
- return STATUS_UNSUCCESSFUL;
+ IoFreeIrp(*Irp);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
#endif
- BaseAddress = MmMapLockedPages(Mdl, KernelMode);
+ AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
- AFD_DbgPrint(MAX_TRACE, ("Mapped user mode buffer at 0x%X.\n", BaseAddress));
+ TdiBuildSend(*Irp, /* I/O Request Packet */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ CompletionRoutine, /* Completion routine */
+ CompletionContext, /* Completion context */
+ Mdl, /* Data buffer */
+ Flags, /* Flags */
+ BufferLength); /* Length of data */
+
+ Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
+ /* Does not block... The MDL is deleted in the receive completion
+ routine. */
- TdiBuildSendDatagram(Irp, /* I/O Request Packet */
- DeviceObject, /* Device object */
- TransportObject, /* File object */
- NULL, /* Completion routine */
- NULL, /* Completion context */
- Mdl, /* Descriptor for data buffer */
- BufferSize, /* Size of data to send */
- ConnectInfo); /* Connection information */
+ return Status;
+}
- Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
+NTSTATUS TdiReceive(
+ PIRP *Irp,
+ PFILE_OBJECT TransportObject,
+ USHORT Flags,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext)
+{
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+ PMDL Mdl;
- MmUnmapLockedPages(BaseAddress, Mdl);
+ DeviceObject = IoGetRelatedDeviceObject(TransportObject);
+ if (!DeviceObject) {
+ AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
- MmUnlockPages(Mdl);
+ *Irp = TdiBuildInternalDeviceControlIrp
+ ( TDI_RECEIVE, /* Sub function */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ NULL, /* Event */
+ Iosb ); /* Status */
- IoFreeMdl(Mdl);
+ if (!*Irp) {
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- ExFreePool(ConnectInfo);
+ AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));
- return Status;
+ Mdl = IoAllocateMdl(Buffer, /* Virtual address */
+ BufferLength, /* Length of buffer */
+ FALSE, /* Not secondary */
+ FALSE, /* Don't charge quota */
+ *Irp); /* Don't use IRP */
+ if (!Mdl) {
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ IoFreeIrp(*Irp);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+#ifdef _MSC_VER
+ try {
#endif
- return STATUS_SUCCESS;
+ MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
+#ifdef _MSC_VER
+ } except (EXCEPTION_EXECUTE_HANDLER) {
+ AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
+ IoFreeMdl(Mdl);
+ IoFreeIrp(*Irp);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+#endif
+
+ AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
+
+ TdiBuildReceive(*Irp, /* I/O Request Packet */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ CompletionRoutine, /* Completion routine */
+ CompletionContext, /* Completion context */
+ Mdl, /* Data buffer */
+ Flags, /* Flags */
+ BufferLength); /* Length of data */
+
+ Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
+ /* Does not block... The MDL is deleted in the receive completion
+ routine. */
+
+ return Status;
}
-NTSTATUS TdiSendDatagram(
+NTSTATUS TdiReceiveDatagram(
+ PIRP *Irp,
PFILE_OBJECT TransportObject,
- LPSOCKADDR Address,
- PMDL Mdl,
- ULONG BufferSize)
+ USHORT Flags,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PTDI_CONNECTION_INFORMATION Addr,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext)
/*
- * FUNCTION: Sends a datagram
+ * FUNCTION: Receives a datagram
* ARGUMENTS:
* TransportObject = Pointer to transport object
- * Address = Remote address to send data to
- * Mdl = MDL of buffer to send
- * BufferSize = Length of buffer
+ * From = Receive filter (NULL if none)
+ * Address = Address of buffer to place remote address
+ * Buffer = Address of buffer to place received data
+ * BufferSize = Address of buffer with length of Buffer (updated)
* RETURNS:
* Status of operation
*/
{
- PTDI_CONNECTION_INFORMATION ConnectInfo;
PDEVICE_OBJECT DeviceObject;
- IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
- KEVENT Event;
- PIRP Irp;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+ PMDL Mdl;
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
@@ -948,144 +958,119 @@
return STATUS_INVALID_PARAMETER;
}
- AFD_DbgPrint(MAX_TRACE,
- ("TdiSendDatagram: TansportObject = %08x\n", TransportObject));
-
- TdiBuildConnectionInfo( &ConnectInfo, Address );
-
- AFD_DbgPrint(MAX_TRACE, ("Point B\n"));
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- AFD_DbgPrint(MAX_TRACE, ("Point 0\n"));
+ *Irp = TdiBuildInternalDeviceControlIrp
+ ( TDI_RECEIVE_DATAGRAM, /* Sub function */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ NULL, /* Event */
+ Iosb ); /* Status */
- Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
- DeviceObject, /* Device object */
- TransportObject, /* File object */
- &Event, /* Event */
- &Iosb); /* Status */
- if (!Irp) {
- AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
- ExFreePool(ConnectInfo);
+ if (!*Irp) {
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
- AFD_DbgPrint(MAX_TRACE, ("Point 1\n"));
+ AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));
-#if 0
- Mdl = IoAllocateMdl(Buffer, /* Virtual address of buffer */
- BufferSize, /* Length of buffer */
- FALSE, /* Not secondary */
- FALSE, /* Don't charge quota */
- NULL); /* Don't use IRP */
+ Mdl = IoAllocateMdl(Buffer, /* Virtual address */
+ BufferLength, /* Length of buffer */
+ FALSE, /* Not secondary */
+ FALSE, /* Don't charge quota */
+ *Irp); /* Don't use IRP */
if (!Mdl) {
- AFD_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
- IoFreeIrp(Irp);
- ExFreePool(ConnectInfo);
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ IoFreeIrp(*Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
+
#ifdef _MSC_VER
try {
#endif
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
#ifdef _MSC_VER
- } except(EXCEPTION_EXECUTE_HANDLER) {
+ } except (EXCEPTION_EXECUTE_HANDLER) {
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
- IoFreeIrp(Irp);
- ExFreePool(ConnectInfo);
- return STATUS_UNSUCCESSFUL;
+ IoFreeMdl(Mdl);
+ IoFreeIrp(*Irp);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
#endif
-#endif
-
- AFD_DbgPrint(MAX_TRACE, ("TdiBuildSendDatagram()\n"));
- TdiBuildSendDatagram(Irp, /* I/O Request Packet */
- DeviceObject, /* Device object */
- TransportObject, /* File object */
- NULL, /* Completion routine */
- NULL, /* Completion context */
- Mdl, /* Descriptor for data buffer */
- BufferSize, /* Size of data to send */
- ConnectInfo); /* Connection information */
- AFD_DbgPrint(MAX_TRACE, ("Returned from TdiBuildSendDatagram\n"));
-
- Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
- AFD_DbgPrint(MAX_TRACE, ("Returned from TdiCall\n"));
-
-#if 0
- MmUnlockPages(Mdl);
- IoFreeMdl(Mdl);
-#endif
+ AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
- ExFreePool(ConnectInfo);
- AFD_DbgPrint(MAX_TRACE, ("Leaving %08x.\n", Status));
+ TdiBuildReceiveDatagram
+ (*Irp, /* I/O Request Packet */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ CompletionRoutine, /* Completion routine */
+ CompletionContext, /* Completion context */
+ Mdl, /* Data buffer */
+ BufferLength,
+ Addr,
+ Addr,
+ Flags); /* Length of data */
+
+ Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
+ /* Does not block... The MDL is deleted in the receive completion
+ routine. */
return Status;
}
-NTSTATUS TdiReceiveDatagram(
+NTSTATUS TdiSendDatagram(
+ PIRP *Irp,
PFILE_OBJECT TransportObject,
- LPSOCKADDR From,
- LPSOCKADDR Address,
- PUCHAR Buffer,
- PULONG BufferSize)
+ PCHAR Buffer,
+ UINT BufferLength,
+ PTDI_CONNECTION_INFORMATION Addr,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext)
/*
- * FUNCTION: Receives a datagram
+ * FUNCTION: Sends a datagram
* ARGUMENTS:
* TransportObject = Pointer to transport object
- * From = Receive filter (NULL if none)
+ * From = Send filter (NULL if none)
* Address = Address of buffer to place remote address
- * Buffer = Address of buffer to place received data
+ * Buffer = Address of buffer to place sendd data
* BufferSize = Address of buffer with length of Buffer (updated)
* RETURNS:
* Status of operation
*/
{
- PTDI_CONNECTION_INFORMATION ReceiveInfo;
- TDI_CONNECTION_INFORMATION ReturnInfo;
PDEVICE_OBJECT DeviceObject;
- IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
- KEVENT Event;
- PIRP Irp;
PMDL Mdl;
- if (From != NULL) {
- /* FIXME: Check that the socket type match the socket */
- }
-
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
return STATUS_INVALID_PARAMETER;
}
- TdiBuildConnectionInfoPair( &ReceiveInfo, From, Address );
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ *Irp = TdiBuildInternalDeviceControlIrp
+ ( TDI_SEND_DATAGRAM, /* Sub function */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ NULL, /* Event */
+ Iosb ); /* Status */
- Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, /* Sub function */
- DeviceObject, /* Device object */
- TransportObject, /* File object */
- &Event, /* Event */
- &Iosb); /* Status */
- if (!Irp) {
+ if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- ExFreePool(ReceiveInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
+ AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength));
+
Mdl = IoAllocateMdl(Buffer, /* Virtual address */
- *BufferSize, /* Length of buffer */
+ BufferLength, /* Length of buffer */
FALSE, /* Not secondary */
FALSE, /* Don't charge quota */
- NULL); /* Don't use IRP */
+ *Irp); /* Don't use IRP */
if (!Mdl) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- IoFreeIrp(Irp);
- ExFreePool(ReceiveInfo);
+ IoFreeIrp(*Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
@@ -1097,33 +1082,26 @@
} except (EXCEPTION_EXECUTE_HANDLER) {
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
IoFreeMdl(Mdl);
- IoFreeIrp(Irp);
- ExFreePool(ReceiveInfo);
+ IoFreeIrp(*Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
#endif
- TdiBuildReceiveDatagram(Irp, /* I/O Request Packet */
- DeviceObject, /* Device object */
- TransportObject, /* File object */
- NULL, /* Completion routine */
- NULL, /* Completion context */
- Mdl, /* Data buffer */
- *BufferSize, /* Size of data buffer */
- ReceiveInfo, /* Connection information */
- &ReturnInfo, /* Connection information */
- TDI_RECEIVE_NORMAL); /* Flags */
- Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
- if (NT_SUCCESS(Status)) {
- *BufferSize = Iosb.Information;
- TdiBuildName(Address, TdiGetRemoteAddress(&ReturnInfo));
- }
-
- MmUnlockPages(Mdl);
-
- IoFreeMdl(Mdl);
+ AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl));
- ExFreePool(ReceiveInfo);
+ TdiBuildSendDatagram
+ (*Irp, /* I/O Request Packet */
+ DeviceObject, /* Device object */
+ TransportObject, /* File object */
+ CompletionRoutine, /* Completion routine */
+ CompletionContext, /* Completion context */
+ Mdl, /* Data buffer */
+ BufferLength, /* Bytes to send */
+ Addr); /* Address */
+
+ Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
+ /* Does not block... The MDL is deleted in the send completion
+ routine. */
return Status;
}
reactos/drivers/net/afd/afd
diff -u -r1.1 -r1.2
--- tdiconn.c 7 Feb 2004 04:50:44 -0000 1.1
+++ tdiconn.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -1,192 +1,64 @@
+/* $Id: tdiconn.c,v 1.2 2004/07/18 22:49:17 arty Exp $
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/afd/tdiconn.c
+ * PURPOSE: Ancillary functions driver
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040708 Created
+ */
#include <afd.h>
+#include "debug.h"
#include "tdiconn.h"
-DWORD TdiAddressSizeFromType(
- ULONG Type)
-/*
- * FUNCTION: Returns the size of a TDI style address of given address type
- * ARGUMENTS:
- * Type = TDI style address type
- * RETURNS:
- * Size of TDI style address, 0 if Type is not valid
- */
-{
- switch (Type) {
- case TDI_ADDRESS_TYPE_IP:
- return sizeof(TA_IP_ADDRESS);
- /* FIXME: More to come */
- }
- AFD_DbgPrint(MIN_TRACE, ("Unknown TDI address type (%d).\n", Type));
- return 0;
-}
-
-DWORD TdiAddressSizeFromName(
- LPSOCKADDR Name)
-/*
- * FUNCTION: Returns the size of a TDI style address equivalent to a
- * WinSock style name
- * ARGUMENTS:
- * Name = WinSock style name
- * RETURNS:
- * Size of TDI style address, 0 if Name is not valid
- */
-{
- switch (Name->sa_family) {
- case AF_INET:
- return sizeof(TA_IP_ADDRESS);
- /* FIXME: More to come */
- }
- AFD_DbgPrint(MIN_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
- return 0;
+UINT TdiAddressSizeFromType( UINT AddressType ) {
+ switch( AddressType ) {
+ case TDI_ADDRESS_TYPE_IP:
+ return sizeof(TA_IP_ADDRESS);
+ default:
+ KeBugCheck( 0 );
+ }
+ return 0;
}
-
-VOID TdiBuildAddressIPv4(
- PTA_IP_ADDRESS Address,
- LPSOCKADDR Name)
-/*
- * FUNCTION: Builds an IPv4 TDI style address
- * ARGUMENTS:
- * Address = Address of buffer to place TDI style IPv4 address
- * Name = Pointer to WinSock style IPv4 name
- */
-{
- Address->TAAddressCount = 1;
- Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
- Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
- Address->Address[0].Address[0].sin_port = ((LPSOCKADDR_IN)Name)->sin_port;
- Address->Address[0].Address[0].in_addr = ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr;
+UINT TaLengthOfAddress( PTA_ADDRESS Addr ) {
+ UINT AddrLen = 2 * sizeof( USHORT ) + Addr->AddressLength;
+ AFD_DbgPrint(MID_TRACE,("AddrLen %x\n", AddrLen));
+ return AddrLen;
}
-
-NTSTATUS TdiBuildAddress(
- PTA_ADDRESS Address,
- LPSOCKADDR Name)
-/*
- * FUNCTION: Builds a TDI style address
- * ARGUMENTS:
- * Address = Address of buffer to place TDI style address
- * Name = Pointer to WinSock style name
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- switch (Name->sa_family) {
- case AF_INET:
- TdiBuildAddressIPv4((PTA_IP_ADDRESS)Address,Name);
- break;
- /* FIXME: More to come */
- default:
- AFD_DbgPrint(MID_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
- Status = STATUS_INVALID_PARAMETER;
- }
-
- return Status;
+UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ) {
+ UINT AddrLen = 2 * sizeof( ULONG ) + Addr->Address[0].AddressLength;
+ AFD_DbgPrint(MID_TRACE,("AddrLen %x\n", AddrLen));
+ return AddrLen;
}
-
-NTSTATUS TdiBuildName(
- LPSOCKADDR Name,
- PTA_ADDRESS Address)
-/*
- * FUNCTION: Builds a WinSock style address
- * ARGUMENTS:
- * Name = Address of buffer to place WinSock style name
- * Address = Pointer to TDI style address
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status = STATUS_SUCCESS;
-
- switch (Address->AddressType) {
- case TDI_ADDRESS_TYPE_IP:
- Name->sa_family = AF_INET;
- ((LPSOCKADDR_IN)Name)->sin_port =
- ((PTDI_ADDRESS_IP)&Address->Address[0])->sin_port;
- ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr =
- ((PTDI_ADDRESS_IP)&Address->Address[0])->in_addr;
- break;
- /* FIXME: More to come */
- default:
- AFD_DbgPrint(MID_TRACE, ("Unknown TDI address type (%d).\n", Address->AddressType));
- Status = STATUS_INVALID_PARAMETER;
- }
-
- return Status;
-
+VOID TaCopyAddressInPlace( PTA_ADDRESS Target,
+ PTA_ADDRESS Source ) {
+ UINT AddrLen = TaLengthOfAddress( Source );
+ RtlCopyMemory( Target, Source, AddrLen );
}
-NTSTATUS TdiBuildConnectionInfoInPlace
-( PTDI_CONNECTION_INFORMATION ConnInfo,
- LPSOCKADDR Name )
-/*
- * FUNCTION: Builds a TDI connection information structure
- * ARGUMENTS:
- * ConnectionInfo = Address of buffer to place connection information
- * Name = Pointer to WinSock style name
- * RETURNS:
- * Status of operation
- */
-{
- ULONG TdiAddressSize;
-
- TdiAddressSize = TdiAddressSizeFromName(Name);
-
- RtlZeroMemory(ConnInfo,
- sizeof(TDI_CONNECTION_INFORMATION) +
- TdiAddressSize);
-
- ConnInfo->OptionsLength = sizeof(ULONG);
- ConnInfo->RemoteAddressLength = TdiAddressSize;
- ConnInfo->RemoteAddress = (PVOID)
- (((PCHAR)ConnInfo) + sizeof(TDI_CONNECTION_INFORMATION));
-
- TdiBuildAddress(ConnInfo->RemoteAddress, Name);
-
- return STATUS_SUCCESS;
+VOID TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target,
+ PTRANSPORT_ADDRESS Source ) {
+ UINT AddrLen = TaLengthOfTransportAddress( Source );
+ RtlCopyMemory( Target, Source, AddrLen );
}
-
-NTSTATUS TdiBuildConnectionInfo(
- PTDI_CONNECTION_INFORMATION *ConnectionInfo,
- LPSOCKADDR Name)
-/*
- * FUNCTION: Builds a TDI connection information structure
- * ARGUMENTS:
- * ConnectionInfo = Address of buffer pointer to allocate connection
- * information on
- * Name = Pointer to WinSock style name
- * RETURNS:
- * Status of operation
- */
-{
- PTDI_CONNECTION_INFORMATION ConnInfo;
- ULONG TdiAddressSize;
- NTSTATUS Status;
-
- TdiAddressSize = TdiAddressSizeFromName(Name);
-
- ConnInfo = (PTDI_CONNECTION_INFORMATION)
- ExAllocatePool(NonPagedPool,
- sizeof(TDI_CONNECTION_INFORMATION) +
- TdiAddressSize);
- if (!ConnInfo)
- return STATUS_INSUFFICIENT_RESOURCES;
+PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ) {
+ UINT AddrLen;
+ PTRANSPORT_ADDRESS A;
- Status = TdiBuildConnectionInfoInPlace( ConnInfo, Name );
+ ASSERT(OtherAddress->TAAddressCount == 1);
+ AddrLen = TaLengthOfTransportAddress( OtherAddress );
+ A = ExAllocatePool( NonPagedPool, AddrLen );
- if( !NT_SUCCESS(Status) )
- ExFreePool( ConnInfo );
- else
- *ConnectionInfo = ConnInfo;
+ if( A )
+ TaCopyTransportAddressInPlace( A, OtherAddress );
- return Status;
+ return A;
}
-
NTSTATUS TdiBuildNullConnectionInfoInPlace
( PTDI_CONNECTION_INFORMATION ConnInfo,
ULONG Type )
@@ -204,8 +76,8 @@
TdiAddressSize = TdiAddressSizeFromType(Type);
RtlZeroMemory(ConnInfo,
- sizeof(TDI_CONNECTION_INFORMATION) +
- TdiAddressSize);
+ sizeof(TDI_CONNECTION_INFORMATION) +
+ TdiAddressSize);
ConnInfo->OptionsLength = sizeof(ULONG);
ConnInfo->RemoteAddressLength = 0;
@@ -235,8 +107,8 @@
ConnInfo = (PTDI_CONNECTION_INFORMATION)
ExAllocatePool(NonPagedPool,
- sizeof(TDI_CONNECTION_INFORMATION) +
- TdiAddressSize);
+ sizeof(TDI_CONNECTION_INFORMATION) +
+ TdiAddressSize);
if (!ConnInfo)
return STATUS_INSUFFICIENT_RESOURCES;
@@ -247,13 +119,44 @@
else
*ConnectionInfo = ConnInfo;
+ ConnInfo->RemoteAddress = (PTA_ADDRESS)&ConnInfo[1];
+ ConnInfo->RemoteAddressLength = TdiAddressSize;
+
+ return Status;
+}
+
+
+NTSTATUS
+TdiBuildConnectionInfoInPlace
+( PTDI_CONNECTION_INFORMATION ConnectionInfo,
+ PTA_ADDRESS Address ) {
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ RtlCopyMemory( ConnectionInfo->RemoteAddress,
+ Address,
+ ConnectionInfo->RemoteAddressLength );
+
+ return Status;
+}
+
+
+NTSTATUS
+TdiBuildConnectionInfo
+( PTDI_CONNECTION_INFORMATION *ConnectionInfo,
+ PTA_ADDRESS Address ) {
+ NTSTATUS Status = TdiBuildNullConnectionInfo( ConnectionInfo,
+ Address->AddressType );
+
+ if( NT_SUCCESS(Status) )
+ TdiBuildConnectionInfoInPlace( *ConnectionInfo, Address );
+
return Status;
}
NTSTATUS
TdiBuildConnectionInfoPair
( PTDI_CONNECTION_INFO_PAIR ConnectionInfo,
- LPSOCKADDR From, LPSOCKADDR To )
+ PTA_ADDRESS From, PTA_ADDRESS To )
/*
* FUNCTION: Fill a TDI_CONNECTION_INFO_PAIR struct will the two addresses
* given.
@@ -266,11 +169,11 @@
*/
{
PCHAR LayoutFrame;
- DWORD SizeOfEntry;
+ UINT SizeOfEntry;
ULONG TdiAddressSize;
/* FIXME: Get from socket information */
- TdiAddressSize = TdiAddressSizeFromName(From);
+ TdiAddressSize = TdiAddressSizeFromType(From->AddressType);
SizeOfEntry = TdiAddressSize + sizeof(TDI_CONNECTION_INFORMATION);
LayoutFrame = (PCHAR)ExAllocatePool(NonPagedPool, 2 * SizeOfEntry);
@@ -282,18 +185,20 @@
RtlZeroMemory( LayoutFrame, 2 * SizeOfEntry );
- PTDI_CONNECTION_INFORMATION
+ {
+ PTDI_CONNECTION_INFORMATION
FromTdiConn = (PTDI_CONNECTION_INFORMATION)LayoutFrame,
ToTdiConn = (PTDI_CONNECTION_INFORMATION)LayoutFrame + SizeOfEntry;
-
- if (From != NULL) {
+
+ if (From != NULL) {
TdiBuildConnectionInfoInPlace( FromTdiConn, From );
- } else {
+ } else {
TdiBuildNullConnectionInfoInPlace( FromTdiConn,
- From->sa_family );
- }
+ From->AddressType );
+ }
- TdiBuildConnectionInfoInPlace( ToTdiConn, To );
+ TdiBuildConnectionInfoInPlace( ToTdiConn, To );
+ }
return STATUS_SUCCESS;
}
reactos/drivers/net/afd/afd
diff -N afd.c
--- afd.c 15 Jun 2004 02:56:13 -0000 1.14
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,219 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver
- * FILE: afd/afd.c
- * PURPOSE: MSAFD kernel mode module
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- * CSH 01/09-2000 Created
- */
-#include <afd.h>
-#include <rosrtl/string.h>
-
-#ifdef DBG
-
-/* See debug.h for debug/trace constants */
-//DWORD DebugTraceLevel = MID_TRACE;
-DWORD DebugTraceLevel = DEBUG_ULTRA;
-
-#endif /* DBG */
-
-
-NPAGED_LOOKASIDE_LIST BufferLookasideList;
-NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
-NPAGED_LOOKASIDE_LIST ListenRequestLookasideList;
-
-
-NTSTATUS
-STDCALL
-AfdFileSystemControl(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- return STATUS_UNSUCCESSFUL;
-}
-
-
-NTSTATUS
-STDCALL
-AfdDispatch(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-/*
- * FUNCTION: IOCTL dispatch routine
- * ARGUMENTS:
- * DeviceObject = Pointer to a device object for this driver
- * Irp = Pointer to a I/O request packet
- * RETURNS:
- * Status of the operation
- */
-{
- NTSTATUS Status;
- PIO_STACK_LOCATION IrpSp;
- BOOL DoComplete = TRUE;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- AFD_DbgPrint(MAX_TRACE, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X), IrpSp->FileObject (0x%X).\n",
- DeviceObject, Irp, IrpSp->FileObject));
-
- Irp->IoStatus.Information = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
- case IOCTL_AFD_BIND:
- Status = AfdDispBind(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_LISTEN:
- Status = AfdDispListen(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_SENDTO:
- Status = AfdDispSendTo(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_RECVFROM:
- Status = AfdDispRecvFrom(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_SELECT:
- Status = AfdDispSelect(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_EVENTSELECT:
- Status = AfdDispEventSelect(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_ENUMNETWORKEVENTS:
- Status = AfdDispEnumNetworkEvents(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_RECV:
- Status = AfdDispRecv(Irp, IrpSp);
- DoComplete = FALSE;
- break;
-
- case IOCTL_AFD_SEND:
- Status = AfdDispSend(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_CONNECT:
- Status = AfdDispConnect(Irp, IrpSp);
- break;
-
- case IOCTL_AFD_GETNAME:
- Status = AfdDispGetName(Irp, IrpSp);
- break;
-
- default:
- Irp->IoStatus.Information = 0;
- AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%X).\n",
- IrpSp->Parameters.DeviceIoControl.IoControlCode));
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- if (Status != STATUS_PENDING && DoComplete) {
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-VOID STDCALL AfdUnload(
- PDRIVER_OBJECT DriverObject)
-/*
- * FUNCTION: Unloads the driver
- * ARGUMENTS:
- * DriverObject = Pointer to driver object created by the system
- */
-{
-}
-
-
-NTSTATUS
-STDCALL
-DriverEntry(
- PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath)
-/*
- * FUNCTION: Called by the system to initialize the driver
- * ARGUMENTS:
- * DriverObject = object describing this driver
- * RegistryPath = path to our configuration entries
- * RETURNS:
- * Status of operation
- */
-{
- PDEVICE_EXTENSION DeviceExt;
- PDEVICE_OBJECT DeviceObject;
- UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\Afd");
- NTSTATUS Status;
-
- Status = IoCreateDevice(DriverObject,
- sizeof(DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_NAMED_PIPE,
- 0,
- FALSE,
- &DeviceObject);
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MIN_TRACE, ("Could not create device (0x%X).\n", Status));
- return Status;
- }
-
- DeviceObject->Flags |= DO_DIRECT_IO;
-
- DeviceExt = DeviceObject->DeviceExtension;
- KeInitializeSpinLock(&DeviceExt->FCBListLock);
- InitializeListHead(&DeviceExt->FCBListHead);
-
- DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdClose;
- DriverObject->MajorFunction[IRP_MJ_READ] = AfdRead;
- DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdWrite;
- DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AfdFileSystemControl;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
- DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AfdClose;
-
- DriverObject->DriverUnload = AfdUnload;
-
-/* ExInitializeNPagedLookasideList(
- &BufferLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(AFD_BUFFER),
- TAG('A', 'F', 'D', 'B'),
- 0);*/
-
-/* ExInitializeNPagedLookasideList(
- &ReadRequestLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(AFD_READ_REQUEST),
- TAG('A', 'F', 'D', 'R'),
- 0);*/
-
- ExInitializeNPagedLookasideList(
- &ListenRequestLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(AFD_LISTEN_REQUEST),
- TAG('A', 'F', 'D', 'L'),
- 0);
-
- return STATUS_SUCCESS;
-}
-
-/* EOF */
reactos/drivers/net/afd/afd
diff -N dispatch.c
--- dispatch.c 3 Jul 2004 17:40:20 -0000 1.15
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,1046 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver
- * FILE: afd/dispatch.c
- * PURPOSE: File object dispatch functions
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- * CSH 01/09-2000 Created
- */
-#include <afd.h>
-
-NTSTATUS AfdpDispRecv(
- PIRP Irp,
- PAFDFCB FCB,
- PFILE_REQUEST_RECVFROM Request,
- PFILE_REPLY_RECVFROM Reply,
- BOOL Continuous)
-/*
- * FUNCTION: Receives data
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * FCB = Pointer to file control block
- * Request = Address of request buffer
- * Reply = Address of reply buffer (same as request buffer)
- * RETURNS:
- * Status of operation
- */
-{
- PAFD_READ_REQUEST ReadRequest;
- NTSTATUS Status;
- KIRQL OldIrql;
- PMDL Mdl;
- UINT i;
-
- KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
- /* Queue a read request and return STATUS_PENDING */
-
- AFD_DbgPrint(MAX_TRACE, ("Queueing read request.\n"));
-
- /*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
- &ReadRequestLookasideList);*/
- ReadRequest = (PAFD_READ_REQUEST)ExAllocatePool(
- NonPagedPool,
- sizeof(AFD_READ_REQUEST));
- if (ReadRequest) {
- ReadRequest->Irp = Irp;
- ReadRequest->RecvFromRequest = Request;
- ReadRequest->RecvFromReply = Reply;
- AFD_DbgPrint(MAX_TRACE,("Reply to %x (%x)\n", Reply,
- ReadRequest->RecvFromReply));
-
- for( i = 0;
- i < ReadRequest->RecvFromRequest->BufferCount;
- i++ ) {
- /* These will be cleaned up in routines.c:FillWSABuffers */
- Mdl = IoAllocateMdl( ReadRequest->RecvFromRequest->Buffers[i].buf,
- ReadRequest->RecvFromRequest->Buffers[i].len,
- FALSE,
- FALSE,
- Irp );
- MmProbeAndLockPages( Mdl, KernelMode, IoWriteAccess );
- ReadRequest->RecvFromRequest->Buffers[i].buf = (PCHAR)Mdl;
- }
-
- InsertTailList( &FCB->ReadRequestQueue, &ReadRequest->ListEntry );
-
- Status = STATUS_PENDING;
- } else {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
-
- TryToSatisfyRecvRequest( FCB, Continuous );
-
- if (IsListEmpty(&FCB->ReadRequestQueue)) /* All recv requests handled */
- Status = STATUS_SUCCESS;
- else
- IoMarkIrpPending( Irp );
-
- KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
-
- return Status;
-}
-
-
-NTSTATUS AfdDispBind(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Binds to an address
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_BIND Request;
- PFILE_REPLY_BIND Reply;
- PAFDFCB FCB;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_BIND)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_BIND))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
-
- Status = TdiOpenAddressFile(
- &FCB->TdiDeviceName,
- &Request->Name,
- &FCB->TdiAddressObjectHandle,
- &FCB->TdiAddressObject);
-
- if (NT_SUCCESS(Status)) {
- AfdRegisterEventHandlers(FCB);
- FCB->State = SOCKET_STATE_BOUND;
- Reply->Status = NO_ERROR;
- } else {
- //FIXME: WSAEADDRNOTAVAIL
- Reply->Status = WSAEINVAL;
- }
- } else
- Status = STATUS_INVALID_PARAMETER;
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS
-STDCALL
-AfdDispCompleteListen(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PVOID Context)
-{
- PAFD_LISTEN_REQUEST ListenRequest = (PAFD_LISTEN_REQUEST) Context;
-
- /* FIXME: Protect ListenRequest->Fcb->ListenRequestQueue */
- RemoveEntryList(&ListenRequest->ListEntry);
-
- AFD_DbgPrint(MAX_TRACE, ("Completed ListenRequest at (0x%X).\n", ListenRequest));
-
- if (NT_SUCCESS(ListenRequest->Iosb.Status))
- {
- if (ListenRequest->Fcb->EventObject != NULL)
- {
- /* FIXME: Protect ListenRequest->Fcb */
- ListenRequest->Fcb->NetworkEvents.lNetworkEvents |= FD_ACCEPT;
- ListenRequest->Fcb->NetworkEvents.iErrorCode[FD_ACCEPT_BIT] = NO_ERROR;
- KeSetEvent(ListenRequest->Fcb->EventObject, EVENT_INCREMENT, FALSE);
- }
- }
-
- ExFreePool(ListenRequest->RequestConnectionInfo);
- ListenRequest->RequestConnectionInfo = NULL;
- ExFreePool(ListenRequest);
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS AfdDispListen(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Starts listening for connections
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_LISTEN Request;
- PFILE_REPLY_LISTEN Reply;
- PAFDFCB FCB;
- PAFD_LISTEN_REQUEST ListenRequest;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- Status = STATUS_INVALID_PARAMETER;
- if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
-
- if (FCB->State == SOCKET_STATE_BOUND)
- {
- /* We have a bound socket so go ahead and create a connection endpoint
- and associate it with the address file object */
-
- Status = TdiOpenConnectionEndpointFile(
- &FCB->TdiDeviceName,
- &FCB->TdiConnectionObjectHandle,
- &FCB->TdiConnectionObject);
-
- if (NT_SUCCESS(Status))
- {
- Status = TdiAssociateAddressFile(
- FCB->TdiAddressObjectHandle,
- FCB->TdiConnectionObject);
-
- if (NT_SUCCESS(Status))
- {
- ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
- if (ListenRequest != NULL)
- {
- ListenRequest->Fcb = FCB;
- /* FIXME: Protect ListenRequestQueue */
- InsertTailList(&FCB->ListenRequestQueue, &ListenRequest->ListEntry);
-
- Status = TdiListen(ListenRequest, AfdDispCompleteListen, ListenRequest);
- if ((Status == STATUS_PENDING) || NT_SUCCESS(Status))
- {
- if (Status != STATUS_PENDING)
- {
- AFD_DbgPrint(MIN_TRACE, ("FIXME: Status (0x%X).\n", Status));
- }
- Status = STATUS_SUCCESS;
- }
- else
- {
- /* FIXME: Cleanup ListenRequest */
- /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
- }
- }
- else
- {
- /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
- Status = STATUS_NO_MEMORY;
- }
- }
- else
- {
- /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
- }
- }
-
- if (NT_SUCCESS(Status)) {
- Reply->Status = NO_ERROR;
- } else {
- Reply->Status = WSAEINVAL;
- }
- }
- else if (FCB->State == SOCKET_STATE_CONNECTED)
- {
- Reply->Status = WSAEISCONN;
- }
- else
- {
- Reply->Status = WSAEINVAL;
- }
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS AfdDispSendTo(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Sends data to an address
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_SENDTO Request;
- PFILE_REPLY_SENDTO Reply;
- PAFDFCB FCB;
- PVOID SystemVirtualAddress;
- PVOID DataBufferAddress;
- ULONG BufferSize;
- ULONG BytesCopied;
- PMDL Mdl;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_SENDTO)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_SENDTO))) {
-
- AFD_DbgPrint(MAX_TRACE, ("FileObject at (0x%X).\n", IrpSp->FileObject));
- AFD_DbgPrint(MAX_TRACE, ("FCB at (0x%X).\n", IrpSp->FileObject->FsContext));
- AFD_DbgPrint(MAX_TRACE, ("CCB at (0x%X).\n", IrpSp->FileObject->FsContext2));
-
- FCB = IrpSp->FileObject->FsContext;
- Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
-
- /* Since we're using bufferred I/O */
- Request->Buffers = (LPWSABUF)(Request + 1);
- BufferSize = WSABufferSize(Request->Buffers, Request->BufferCount);
-
-
- /* FIXME: Should we handle special cases here? */
- if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
- BufferSize += sizeof(IPv4_HEADER);
- }
-
-
- if (BufferSize != 0) {
- AFD_DbgPrint(MAX_TRACE, ("Allocating %d bytes for send buffer.\n", BufferSize));
- SystemVirtualAddress = ExAllocatePool(NonPagedPool, BufferSize);
- if (!SystemVirtualAddress) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* FIXME: Should we handle special cases here? */
- if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
- DataBufferAddress = ((PCHAR)SystemVirtualAddress) + sizeof(IPv4_HEADER);
-
- /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
- ((PSOCKADDR_IN)&FCB->SocketName)->sin_addr.S_un.S_addr = 0x0100007F;
-
- BuildIPv4Header(
- (PIPv4_HEADER)SystemVirtualAddress,
- BufferSize,
- FCB->Protocol,
- &FCB->SocketName,
- &Request->To);
- } else {
- DataBufferAddress = SystemVirtualAddress;
- }
-
- Status = MergeWSABuffers(
- Request->Buffers,
- Request->BufferCount,
- DataBufferAddress,
- BufferSize,
- &BytesCopied);
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- return Status;
- }
- } else {
- SystemVirtualAddress = NULL;
- BytesCopied = 0;
- }
-
- Mdl = IoAllocateMdl(
- SystemVirtualAddress, /* Virtual address of buffer */
- BufferSize, /* Length of buffer */
- FALSE, /* Not secondary */
- FALSE, /* Don't charge quota */
- NULL); /* Don't use IRP */
- if (!Mdl) {
- ExFreePool(SystemVirtualAddress);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- MmBuildMdlForNonPagedPool(Mdl);
-
- AFD_DbgPrint(MAX_TRACE, ("System virtual address is (0x%X).\n", SystemVirtualAddress));
- AFD_DbgPrint(MAX_TRACE, ("MDL for data buffer is at (0x%X).\n", Mdl));
-
- AFD_DbgPrint(MAX_TRACE, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl->MdlFlags));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", Mdl->Next));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", Mdl->Size));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl->MappedSystemVa));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", Mdl->StartVa));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl->ByteCount));
- AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl->ByteOffset));
-
-#if 0
-#ifdef _MSC_VER
- try {
-#endif
- MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
-#ifdef _MSC_VER
- } except(EXCEPTION_EXECUTE_HANDLER) {
- AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
- IoFreeMdl(Mdl);
- if (BufferSize != 0) {
- ExFreePool(SystemVirtualAddress);
- }
- return STATUS_UNSUCCESSFUL;
- }
-#endif
-#endif
-
- if (!FCB->TdiAddressObject) {
- struct sockaddr_in BindName;
-
- RtlZeroMemory(&BindName,sizeof(BindName));
- BindName.sin_family = AF_INET;
-
- Status = TdiOpenAddressFile
- (&FCB->TdiDeviceName,
- (SOCKADDR *)&BindName,
- &FCB->TdiAddressObjectHandle,
- &FCB->TdiAddressObject);
-
- if (NT_SUCCESS(Status)) {
- AfdRegisterEventHandlers(FCB);
- FCB->State = SOCKET_STATE_BOUND;
- Reply->Status = NO_ERROR;
- } else {
- //FIXME: WSAEADDRNOTAVAIL
- Reply->Status = WSAEINVAL;
- MmUnlockPages(Mdl);
- IoFreeMdl(Mdl);
- return Status;
- }
- }
-
- Status = TdiSendDatagram(FCB->TdiAddressObject,
- &Request->To,
- Mdl,
- BufferSize);
-
- /* FIXME: Assumes synchronous operation */
-#if 0
- MmUnlockPages(Mdl);
-#endif
-
- IoFreeMdl(Mdl);
-
- if (BufferSize != 0) {
- ExFreePool(SystemVirtualAddress);
- }
-
- Reply->NumberOfBytesSent = BufferSize;
- Reply->Status = NO_ERROR;
- } else
- Status = STATUS_INVALID_PARAMETER;
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS AfdDispRecvFrom(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Receives data from an address
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_RECVFROM Request;
- PFILE_REPLY_RECVFROM Reply;
- PAFDFCB FCB;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_RECVFROM)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_RECVFROM))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
- /* Since we're using bufferred I/O */
- Request->Buffers = (LPWSABUF)(Request + 1);
-
- Status = AfdpDispRecv(
- Irp,
- FCB,
- Request,
- Reply,
- FALSE);
- } else {
- Status = STATUS_INVALID_PARAMETER;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-typedef enum {
- soRead,
- soWrite,
- soExcept
-} SelectOperation;
-
-
-DWORD AfdpDispSelectEx(
- LPFD_SET FDSet,
- SelectOperation Operation)
-{
- PFILE_OBJECT FileObject;
- NTSTATUS Status;
- PAFDFCB Current;
- KIRQL OldIrql;
- DWORD Count;
- ULONG i;
-
- AFD_DbgPrint(MAX_TRACE, ("FDSet (0x%X) Operation (0x%X).\n",
- FDSet, Operation));
-
- AFD_DbgPrint(MAX_TRACE, ("FDSet->fd_count (0x%X).\n", FDSet->fd_count));
-
- Count = 0;
- for (i = 0; i < FDSet->fd_count; i++) {
-
- AFD_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", FDSet->fd_array[i]));
-
- Status = ObReferenceObjectByHandle(
- (HANDLE)FDSet->fd_array[i],
- 0,
- IoFileObjectType,
- KernelMode,
- (PVOID*)&FileObject,
- NULL);
- if (NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("File object is at (0x%X).\n", FileObject));
-
- Current = FileObject->FsContext;
-
- switch (Operation) {
- case soRead:
- KeAcquireSpinLock(&Current->ReceiveQueueLock, &OldIrql);
- if (!IsListEmpty(&Current->ReceiveQueue)) {
- AFD_DbgPrint(MAX_TRACE, ("Socket is readable.\n"));
- Count++;
- }
- KeReleaseSpinLock(&Current->ReceiveQueueLock, OldIrql);
- break;
- case soWrite:
- /* FIXME: How can we check for writability? */
- Count++;
- break;
- case soExcept:
- /* FIXME: What is this? */
- Count++;
- break;
- }
-
- ObDereferenceObject(FileObject);
- }
- }
-
- return Count;
-}
-
-NTSTATUS AfdDispSelect(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Checks if sockets have data in the receive buffers
- * and/or if client can send data
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_SELECT Request;
- PFILE_REPLY_SELECT Reply;
- DWORD SocketCount;
- PAFDFCB FCB;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_SELECT)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_SELECT))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_SELECT)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_SELECT)Irp->AssociatedIrp.SystemBuffer;
-
- AFD_DbgPrint(MAX_TRACE, ("R (0x%X) W (0x%X).\n",
- Request->ReadFDSet, Request->WriteFDSet));
-
- SocketCount = 0;
-
- if (Request->WriteFDSet) {
- AFD_DbgPrint(MAX_TRACE, ("Write.\n"));
- SocketCount += AfdpDispSelectEx(Request->WriteFDSet, soWrite);
- }
- if (Request->ReadFDSet) {
- AFD_DbgPrint(MAX_TRACE, ("Read.\n"));
- SocketCount += AfdpDispSelectEx(Request->ReadFDSet, soRead);
- }
- if (Request->ExceptFDSet) {
- SocketCount += AfdpDispSelectEx(Request->ExceptFDSet, soExcept);
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Sockets selected (0x%X).\n", SocketCount));
-
- Reply->Status = NO_ERROR;
- Reply->SocketCount = SocketCount;
- Status = STATUS_SUCCESS;
- } else
- Status = STATUS_INVALID_PARAMETER;
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-NTSTATUS AfdDispEventSelect(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Associate an event object with one or more network events
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_EVENTSELECT Request;
- PFILE_REPLY_EVENTSELECT Reply;
- PKEVENT Event;
- PAFDFCB FCB;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_EVENTSELECT)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_EVENTSELECT))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
-
- /* FIXME: Need to ObDereferenceObject(FCB->EventObject) this somewhere */
- Status = ObReferenceObjectByHandle(
- Request->hEventObject,
- 0,
- ExEventObjectType,
- UserMode,
- (PVOID*)&Event,
- NULL);
- if (NT_SUCCESS(Status)) {
- FCB->NetworkEvents.lNetworkEvents = Request->lNetworkEvents;
- FCB->EventObject = Event;
- Reply->Status = NO_ERROR;
- Status = STATUS_SUCCESS;
- }
- else
- {
- AFD_DbgPrint(MID_TRACE, ("Bad event handle (0x%X).\n", Status));
-
- Reply->Status = WSAEINVAL;
- Status = STATUS_SUCCESS;
- }
- }
- else
- {
- Status = STATUS_INVALID_PARAMETER;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-NTSTATUS AfdDispEnumNetworkEvents(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Reports network events
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_ENUMNETWORKEVENTS Request;
- PFILE_REPLY_ENUMNETWORKEVENTS Reply;
- HANDLE EventObject;
- PAFDFCB FCB;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_ENUMNETWORKEVENTS)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_ENUMNETWORKEVENTS))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_ENUMNETWORKEVENTS)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_ENUMNETWORKEVENTS)Irp->AssociatedIrp.SystemBuffer;
-
- EventObject = (HANDLE)Request->hEventObject;
-
- RtlCopyMemory(
- &Reply->NetworkEvents,
- &FCB->NetworkEvents,
- sizeof(WSANETWORKEVENTS));
-
- RtlZeroMemory(
- &FCB->NetworkEvents,
- sizeof(WSANETWORKEVENTS));
-
- if (EventObject != NULL) {
- ZwClearEvent(EventObject);
- }
-
- Reply->Status = NO_ERROR;
- Status = STATUS_SUCCESS;
- } else
- Status = STATUS_INVALID_PARAMETER;
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS AfdDispRecv(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Receives data from an address
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_RECVFROM Request;
- PFILE_REPLY_RECVFROM Reply;
- PAFDFCB FCB;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_RECV)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_RECV))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
-
- Status = AfdpDispRecv(
- Irp,
- FCB,
- Request,
- Reply,
- TRUE);
- Reply->NumberOfBytesRecvd = 0; /* FIXME */
- Reply->Status = NO_ERROR;
- } else {
- Status = STATUS_INVALID_PARAMETER;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS AfdDispSend(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Sends data
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status = STATUS_SUCCESS;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_SEND Request;
- PFILE_REPLY_SEND Reply;
- PAFDFCB FCB;
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- if ((InputBufferLength >= sizeof(FILE_REQUEST_SEND)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_SEND))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_SEND)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_SEND)Irp->AssociatedIrp.SystemBuffer;
-
- Reply->NumberOfBytesSent = 0;
- Reply->Status = NO_ERROR;
- } else
- Status = STATUS_INVALID_PARAMETER;
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS AfdDispConnect(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Connect to a remote peer
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_CONNECT Request;
- PFILE_REPLY_CONNECT Reply;
- PAFDFCB FCB;
- SOCKADDR_IN LocalAddress;
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- Status = STATUS_INVALID_PARAMETER;
- if ((InputBufferLength >= sizeof(FILE_REQUEST_CONNECT)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_CONNECT))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_CONNECT)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_CONNECT)Irp->AssociatedIrp.SystemBuffer;
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- if (FCB->State == SOCKET_STATE_BOUND) {
- Reply->Status = WSAEADDRINUSE;
- } else if (FCB->State == SOCKET_STATE_CONNECTED) {
- Reply->Status = WSAEISCONN;
- } else {
- /* We have an unbound socket so go ahead and create an address
- file object and a connection endpoint and associate the two */
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- /* FIXME: Get from client */
- LocalAddress.sin_family = AF_INET;
- LocalAddress.sin_port = 1700;
- LocalAddress.sin_addr.S_un.S_addr = 0x0; /* Dynamically allocate */
-
- Status = TdiOpenAddressFile(
- &FCB->TdiDeviceName,
- (LPSOCKADDR)&LocalAddress,
- &FCB->TdiAddressObjectHandle,
- &FCB->TdiAddressObject);
-
- if (NT_SUCCESS(Status)) {
- AfdRegisterEventHandlers(FCB);
- FCB->State = SOCKET_STATE_BOUND;
- }
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- if (NT_SUCCESS(Status)) {
- Status = TdiOpenConnectionEndpointFile(
- &FCB->TdiDeviceName,
- &FCB->TdiConnectionObjectHandle,
- &FCB->TdiConnectionObject);
- }
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- if (NT_SUCCESS(Status)) {
- Status = TdiAssociateAddressFile(
- FCB->TdiAddressObjectHandle,
- FCB->TdiConnectionObject);
- }
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- if (NT_SUCCESS(Status)) {
- /* Now attempt to connect to the remote peer */
- Status = TdiConnect(
- FCB->TdiConnectionObject,
- Request->name);
- }
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- if (NT_SUCCESS(Status)) {
- FCB->State = SOCKET_STATE_CONNECTED;
- Reply->Status = NO_ERROR;
- } else {
- Reply->Status = WSAEINVAL;
- }
- }
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-NTSTATUS AfdDispGetName(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp)
-/*
- * FUNCTION: Get socket name
- * ARGUMENTS:
- * Irp = Pointer to I/O request packet
- * IrpSp = Pointer to current stack location of Irp
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- UINT InputBufferLength;
- UINT OutputBufferLength;
- PFILE_REQUEST_GETNAME Request;
- PFILE_REPLY_GETNAME Reply;
- PAFDFCB FCB;
- PFILE_OBJECT FileObject;
- PMDL Mdl;
- PTDI_ADDRESS_INFO AddressInfoBuffer;
- ULONG AddressInfoSize;
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
- OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
- /* Validate parameters */
- Status = STATUS_INVALID_PARAMETER;
- if ((InputBufferLength >= sizeof(FILE_REQUEST_GETNAME)) &&
- (OutputBufferLength >= sizeof(FILE_REPLY_GETNAME))) {
- FCB = IrpSp->FileObject->FsContext;
-
- Request = (PFILE_REQUEST_GETNAME)Irp->AssociatedIrp.SystemBuffer;
- Reply = (PFILE_REPLY_GETNAME)Irp->AssociatedIrp.SystemBuffer;
-
- AFD_DbgPrint(MIN_TRACE, ("\n"));
-
- if (Request->Peer) {
- if (FCB->State != SOCKET_STATE_CONNECTED) {
- Reply->Status = WSAENOTCONN;
- return STATUS_UNSUCCESSFUL;
[truncated at 1000 lines; 50 more skipped]
reactos/drivers/net/afd/afd
diff -N opnclose.c
--- opnclose.c 15 Jun 2004 02:56:13 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,285 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver
- * FILE: afd/opnclose.c
- * PURPOSE: File object creation and destruction
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- * CSH 01/09-2000 Created
- */
-#include <afd.h>
-
-PAFDFCB AfdInitializeFCB(
- PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT FileObject OPTIONAL)
-/*
- * FUNCTION: Allocates and initializes a File Control Block structure
- */
-{
- PAFDFCB NewFCB;
-
- NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
- if (!NewFCB)
- return NULL;
-
- RtlZeroMemory(NewFCB, sizeof(AFDFCB));
-
- ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource);
- ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource);
-
- NewFCB->DeviceExt = DeviceExt;
- NewFCB->ReferenceCount = 1;
- NewFCB->OpenHandleCount = 1;
-
- NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
- NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
-
- InitializeListHead(&NewFCB->CCBListHead);
-
- InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
-
- InitializeListHead(&NewFCB->ReceiveQueue);
- KeInitializeSpinLock(&NewFCB->ReceiveQueueLock);
-
- InitializeListHead(&NewFCB->ReadRequestQueue);
-
- InitializeListHead(&NewFCB->ListenRequestQueue);
-
- if (FileObject)
- FileObject->FsContext = (PVOID)NewFCB;
-
- AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
-
- return NewFCB;
-}
-
-
-PAFDCCB AfdInitializeCCB(
- PAFDFCB FCB,
- PFILE_OBJECT FileObject)
-/*
- * FUNCTION: Allocates and initializes a Context Control Block structure
- */
-{
- PAFDCCB NewCCB;
-
- NewCCB = ExAllocatePool(NonPagedPool, sizeof(AFDCCB));
- if (!NewCCB)
- return NULL;
-
- RtlZeroMemory(NewCCB, sizeof(AFDCCB));
-
- NewCCB->FileObject = FileObject;
-
- FileObject->FsContext2 = (PVOID)NewCCB;
-
- InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
-
- AFD_DbgPrint(MAX_TRACE, ("CCB created for file object (0x%X) at (0x%X).\n", FileObject, NewCCB));
-
- return NewCCB;
-}
-
-
-NTSTATUS
-STDCALL
-AfdCreate(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PAFD_SOCKET_INFORMATION SocketInfo;
- PFILE_FULL_EA_INFORMATION EaInfo;
- PDEVICE_EXTENSION DeviceExt;
- NTSTATUS Status;
- ULONG EaLength;
- PAFDFCB FCB;
- PAFDCCB CCB;
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = IrpSp->FileObject;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- assert(DeviceObject);
-
- DeviceExt = DeviceObject->DeviceExtension;
-
- EaInfo = Irp->AssociatedIrp.SystemBuffer;
-
- /* Parameter check */
- if (!EaInfo) {
- AFD_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
- return STATUS_INVALID_PARAMETER;
- }
-
- SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + EaInfo->EaNameLength);
-
- EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
- EaInfo->EaNameLength +
- EaInfo->EaValueLength;
-
- if (EaLength < sizeof(FILE_FULL_EA_INFORMATION) +
- AFD_SOCKET_LENGTH + sizeof(AFD_SOCKET_INFORMATION)) {
- AFD_DbgPrint(MIN_TRACE, ("EA information has invalid length.\n"));
- return STATUS_INVALID_PARAMETER;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) length is (%d).\n", EaInfo, EaLength));
-
- /* FIXME: File/socket could already be open, do a search for it */
-
- FCB = AfdInitializeFCB(DeviceExt, FileObject);
-
- CCB = AfdInitializeCCB(FCB, FileObject);
-
- if (CCB && FCB) {
- FCB->CommandChannel = SocketInfo->CommandChannel;
-
- if (!FCB->CommandChannel) {
- FCB->AddressFamily = SocketInfo->AddressFamily;
- FCB->SocketType = SocketInfo->SocketType;
- FCB->Protocol = SocketInfo->Protocol;
- FCB->SocketName = SocketInfo->Name;
- FCB->HelperContext = SocketInfo->HelperContext;
- FCB->NotificationEvents = SocketInfo->NotificationEvents;
-
- FCB->TdiDeviceName.Length = 0;
- FCB->TdiDeviceName.MaximumLength = SocketInfo->TdiDeviceName.MaximumLength;
- FCB->TdiDeviceName.Buffer = ExAllocatePool(
- NonPagedPool,
- FCB->TdiDeviceName.MaximumLength);
-
- if (FCB->TdiDeviceName.Buffer) {
- RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
-
- AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
-
- /* Open address file now for raw sockets */
- if (FCB->SocketType == SOCK_RAW) {
- AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
-
- Status = TdiOpenAddressFile(
- &FCB->TdiDeviceName,
- &SocketInfo->Name,
- &FCB->TdiAddressObjectHandle,
- &FCB->TdiAddressObject);
- if (NT_SUCCESS(Status)) {
- Status = AfdRegisterEventHandlers(FCB);
- if (NT_SUCCESS(Status)) {
- FCB->State = SOCKET_STATE_BOUND;
- } else {
- AFD_DbgPrint(MAX_TRACE, ("AfdRegisterEventHandlers() failed (0x%X).\n", Status));
- }
- } else {
- AFD_DbgPrint(MAX_TRACE, ("TdiOpenAddressFile() failed (0x%X).\n", Status));
- }
- } else
- Status = STATUS_SUCCESS;
- } else
- Status = STATUS_INSUFFICIENT_RESOURCES;
- } else
- Status = STATUS_SUCCESS;
- } else
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- if (!NT_SUCCESS(Status)) {
- /* FIXME: Cleanup */
- AFD_DbgPrint(MAX_TRACE, ("FIXME: Cleanup.\n"));
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
-
- return Status;
-}
-
-
-VOID
-AfdKillListenRequests(PAFDFCB FCB)
-{
- /* FIXME: Implement */
- AFD_DbgPrint(MIN_TRACE, ("Unimplemented.\n"));
-
- /*ExFreeToNPagedLookasideList(&ListenRequestLookasideList,
- (PVOID)ListenRequest);*/
-}
-
-
-NTSTATUS
-STDCALL
-AfdClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = IrpSp->FileObject;
- NTSTATUS Status;
- PAFDFCB FCB;
- PAFDCCB CCB;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- assert(DeviceObject);
- assert(FileObject);
-
- FCB = FileObject->FsContext;
- CCB = FileObject->FsContext2;
-
- switch (IrpSp->MajorFunction) {
- /* Close a file object */
- case IRP_MJ_CLOSE:
- FCB->ReferenceCount--;
- if (FCB->ReferenceCount < 1) {
- if (!FCB->CommandChannel) {
- /* Kill outstanding listen requests */
- AfdKillListenRequests(FCB);
-
- /* Close TDI connection file object */
- if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
- TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
- FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
- }
-
- /* Close TDI address file object */
- if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
- AfdDeregisterEventHandlers(FCB);
- TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
- FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
- }
- }
-
- ExFreePool(FCB);
- }
-
- Status = STATUS_SUCCESS;
- break;
-
- /* Release resources bound to a file object */
- case IRP_MJ_CLEANUP:
- FCB->OpenHandleCount--;
- Status = STATUS_SUCCESS;
-
- ExFreePool(CCB);
-
- break;
-
- default:
- Status = STATUS_INVALID_DEVICE_REQUEST;
- }
-
-// ExFreePool(CCB);
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", Irp));
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-/* EOF */
reactos/drivers/net/afd/afd
diff -N rdwr.c
--- rdwr.c 3 Jul 2004 17:40:20 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,118 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver
- * FILE: afd/rdwr.c
- * PURPOSE: File object read/write functions
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- * CSH 01/09-2000 Created
- */
-#include <afd.h>
-
-NTSTATUS AfdReadFile(
- PDEVICE_EXTENSION DeviceExt,
- PFILE_OBJECT FileObject,
- PVOID Buffer,
- ULONG Length,
- ULONG Offset)
-/*
- * FUNCTION: Reads data from a file
- */
-{
- UNIMPLEMENTED
-
- return STATUS_UNSUCCESSFUL;
-}
-
-
-NTSTATUS
-STDCALL
-AfdRead(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
-#if 1
- UNIMPLEMENTED
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- return STATUS_UNSUCCESSFUL;
-#else
- PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
- PIO_STACK_LOCATION IoSp = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = IoSp->FileObject;
- NTSTATUS Status;
- ULONG Length;
- PVOID Buffer;
- ULONG Offset;
-
- Length = IoSp->Parameters.Read.Length;
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
- Offset = IoSp->Parameters.Read.ByteOffset.u.LowPart;
-
- Status = AfdReadFile(DeviceExt, FileObject, Buffer, Length, Offset);
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Length;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-#endif
-}
-
-
-NTSTATUS
-STDCALL
-AfdWrite(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
-{
- PIO_STACK_LOCATION IoSp = IoGetCurrentIrpStackLocation(Irp);
- PFILE_OBJECT FileObject = IoSp->FileObject;
- NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
- ULONG Length;
- PVOID Buffer;
- ULONG Offset;
- PAFDFCB FCB;
- PAFDCCB CCB;
-
- FCB = FileObject->FsContext;
- CCB = FileObject->FsContext2;
-
- assert(FCB);
- assert(CCB);
-
- Length = IoSp->Parameters.Write.Length;
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
- Offset = IoSp->Parameters.Write.ByteOffset.u.LowPart;
-
- AFD_DbgPrint(MAX_TRACE, ("Called. Length (%d) Buffer (0x%X) Offset (0x%X)\n",
- Length, Buffer, Offset));
-
- assert((FCB->SocketType == SOCK_STREAM) || (FCB->SocketType == SOCK_DGRAM));
-
- switch (FCB->SocketType) {
- case SOCK_STREAM:
- /* FIXME: Support connectionful communication */
- break;
- case SOCK_DGRAM:
- /* Connectionless communication */
- //Status = TdiSendDatagram(FCB->TdiAddressObject, WH2N(2000), 0x7F000001, Buffer, Length);
- //if (!NT_SUCCESS(Status)) {
- Length = 0;
- //}
- break;
- case SOCK_RAW:
- /* FIXME: Support raw communication */
- break;
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Length;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
-
- return Status;
-}
-
-/* EOF */
reactos/drivers/net/afd/afd
diff -N routines.c
--- routines.c 15 Jun 2004 02:56:13 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,316 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver
- * FILE: afd/routines.c
- * PURPOSE: Support routines
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- * CSH 01/02-2001 Created
- */
-#include <afd.h>
-#include <debug.h>
-
-#ifndef DONT_USE_ME_THIS_WAY_IM_LIFTED_FROM_NTOSKRNL_XXX_DO_THIS_THE_RIGHT_WAY
-LONG FASTCALL
-XxInterlockedExchange(PLONG Target,
- LONG Value);
-
-__asm__("\n\t.global @XxInterlockedExchange@8\n\t"
- "@XxInterlockedExchange@8:\n\t"
- "xchgl %edx,(%ecx)\n\t"
- "movl %edx,%eax\n\t"
- "ret\n\t");
-
-#define InterlockedExchange XxInterlockedExchange
-#endif
-
-VOID DumpName(
- LPSOCKADDR Name)
-{
- AFD_DbgPrint(MIN_TRACE, ("DumpName:\n"));
- AFD_DbgPrint(MIN_TRACE, (" sa_family: %d\n", Name->sa_family));
- AFD_DbgPrint(MIN_TRACE, (" sin_port: %d\n", WN2H(((LPSOCKADDR_IN)Name)->sin_port)));
- AFD_DbgPrint(MIN_TRACE, (" in_addr: 0x%x\n", WN2H(((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr)));
-}
-
-
-ULONG WSABufferSize(
- LPWSABUF Buffers,
- DWORD BufferCount)
-{
- ULONG i;
- LPWSABUF p;
- ULONG Count = 0;
-
- p = Buffers;
- for (i = 0; i < BufferCount; i++) {
- Count += p->len;
- p++;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
-
- return Count;
-}
-
-
-NTSTATUS MergeWSABuffers(
- LPWSABUF Buffers,
- DWORD BufferCount,
- PVOID Destination,
- ULONG MaxLength,
- PULONG BytesCopied)
-{
- ULONG Length;
- LPWSABUF p;
- ULONG i;
-
- *BytesCopied = 0;
- if (BufferCount == 0)
- return STATUS_SUCCESS;
-
- p = Buffers;
-
- AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
- AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
-
- for (i = 0; i < BufferCount; i++) {
- Length = p->len;
- if (Length > MaxLength)
- /* Don't copy out of bounds */
- Length = MaxLength;
-
- RtlCopyMemory(Destination, p->buf, Length);
- Destination += Length;
- AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
- p++;
- AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
-
- *BytesCopied += Length;
-
- MaxLength -= Length;
- if (MaxLength == 0)
- /* Destination buffer is full */
- break;
- }
-
- return STATUS_SUCCESS;
-}
-
-VOID TryToSatisfyRecvRequest( PAFDFCB FCB, BOOL Continuous ) {
- PAFD_READ_REQUEST ReadRequest;
- PLIST_ENTRY Entry;
- NTSTATUS Status;
- ULONG Count = 0;
-
- AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
-
- while (!IsListEmpty(&FCB->ReadRequestQueue) &&
- !IsListEmpty(&FCB->ReceiveQueue)) {
- AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
-
- Entry = RemoveHeadList(&FCB->ReadRequestQueue);
- ReadRequest = CONTAINING_RECORD(Entry, AFD_READ_REQUEST, ListEntry);
-
- AFD_DbgPrint(MAX_TRACE,("ReadRequest: (li) %x %x %x\n",
- ReadRequest->Irp,
- ReadRequest->RecvFromRequest,
- ReadRequest->RecvFromReply));
-
- Status = FillWSABuffers(
- FCB,
- ReadRequest->RecvFromRequest->Buffers,
- ReadRequest->RecvFromRequest->BufferCount,
- &Count,
- Continuous );
-
- ReadRequest->RecvFromReply->NumberOfBytesRecvd = Count;
- ReadRequest->RecvFromReply->Status = NO_ERROR;
-
- ReadRequest->Irp->IoStatus.Information =
- sizeof(*ReadRequest->RecvFromReply);
- ReadRequest->Irp->IoStatus.Status = Status;
-
- AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", ReadRequest->Irp));
-
- IoSetCancelRoutine(ReadRequest->Irp, NULL);
- IoCompleteRequest(ReadRequest->Irp, IO_NETWORK_INCREMENT);
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Bytes received (0x%X).\n", Count));
-}
-
-/*
- * NOTES: ReceiveQueueLock must be acquired for the FCB when called
- */
-NTSTATUS FillWSABuffers(
- PAFDFCB FCB,
- LPWSABUF Buffers,
- DWORD BufferCount,
- PULONG BytesCopied,
- BOOL Continuous)
-{
- PUCHAR DstData, SrcData;
- UINT DstSize, SrcSize;
- UINT Count, Total;
- PAFD_BUFFER SrcBuffer;
- PMDL Mdl;
- PLIST_ENTRY Entry;
-
- *BytesCopied = 0;
- if (BufferCount == 0)
- return STATUS_SUCCESS;
-
- if (IsListEmpty(&FCB->ReceiveQueue))
- return STATUS_SUCCESS;
-
- Entry = RemoveHeadList(&FCB->ReceiveQueue);
- SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
- SrcData = SrcBuffer->Buffer.buf + SrcBuffer->Offset;
- SrcSize = SrcBuffer->Buffer.len - SrcBuffer->Offset;
-
- /* First buffer: map the pages so we can access them */
- Mdl = (PMDL)Buffers->buf;
- DstData = MmMapLockedPages( Mdl, KernelMode );
- DstSize = Buffers->len;
-
- /* Copy the data */
- for (Total = 0;;) {
- /* Find out how many bytes we can copy at one time */
- if (DstSize < SrcSize)
- Count = DstSize;
- else
- Count = SrcSize;
-
- AFD_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcData (0x%X) Count (0x%X).\n",
- DstData, SrcData, Count));
-
- RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
-
- Total += Count;
-
- SrcSize -= Count;
- if (SrcSize == 0) {
- ExFreePool(SrcBuffer->Buffer.buf);
- ExFreePool(SrcBuffer);
-
- /* No more bytes in source buffer. Proceed to the next buffer
- in the source buffer chain if there is one */
- if (IsListEmpty(&FCB->ReceiveQueue)) {
- SrcBuffer = NULL;
- SrcData = 0;
- SrcSize = 0;
- break;
- }
-
- Entry = RemoveHeadList(&FCB->ReceiveQueue);
- SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
- SrcData = SrcBuffer->Buffer.buf;
- SrcSize = SrcBuffer->Buffer.len;
- }
-
- DstSize -= Count;
- if (DstSize == 0) {
- /* No more bytes in destination buffer. Proceed to
- the next buffer in the destination buffer chain */
- BufferCount--;
- if (BufferCount < 1)
- break;
-
- /* And cleanup the pages. */
- MmUnmapLockedPages( DstData, Mdl );
- MmUnlockPages( Mdl );
- IoFreeMdl( Mdl );
-
- Buffers++;
- Mdl = (PMDL)Buffers->buf;
- DstData = MmMapLockedPages( Mdl, KernelMode );
- DstSize = Buffers->len;
- }
- }
-
- if (SrcSize > 0) {
- SrcBuffer->Offset += Total;
- InsertHeadList(&FCB->ReceiveQueue, Entry);
- } else if (SrcBuffer != NULL) {
- ExFreePool(SrcBuffer->Buffer.buf);
- ExFreePool(SrcBuffer);
- }
-
- *BytesCopied = Total;
-
- return STATUS_SUCCESS;
-}
-
-ULONG ChecksumCompute(
- PVOID Data,
- UINT Count,
- ULONG Seed)
-/*
- * FUNCTION: Calculate checksum of a buffer
- * ARGUMENTS:
- * Data = Pointer to buffer with data
- * Count = Number of bytes in buffer
- * Seed = Previously calculated checksum (if any)
- * RETURNS:
- * Checksum of buffer
- */
-{
- /* FIXME: This should be done in assembler */
-
- register ULONG Sum = Seed;
-
- while (Count > 1) {
- Sum += *(PUSHORT)Data;
- Count -= 2;
- Data = (PVOID) ((ULONG_PTR) Data + 2);
- }
-
- /* Add left-over byte, if any */
- if (Count > 0)
- Sum += *(PUCHAR)Data;
-
- /* Fold 32-bit sum to 16 bits */
- while (Sum >> 16)
- Sum = (Sum & 0xFFFF) + (Sum >> 16);
-
- return ~Sum;
-}
-
-VOID BuildIPv4Header(
- PIPv4_HEADER IPHeader,
- ULONG TotalSize,
- ULONG Protocol,
- PSOCKADDR SourceAddress,
- PSOCKADDR DestinationAddress)
-{
- PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
- PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
-
- /* Version = 4, Length = 5 DWORDs */
- IPHeader->VerIHL = 0x45;
- /* Normal Type-of-Service */
- IPHeader->Tos = 0;
- /* Length of header and data */
- IPHeader->TotalLength = WH2N((USHORT)TotalSize);
- /* Identification */
- IPHeader->Id = 0;
- /* One fragment at offset 0 */
- IPHeader->FlagsFragOfs = 0;
- /* Time-to-Live is 128 */
- IPHeader->Ttl = 128;
- /* Protocol number */
- IPHeader->Protocol = Protocol;
- /* Checksum is 0 (calculated later) */
- IPHeader->Checksum = 0;
- /* Source address */
- IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
- /* Destination address */
- IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
-
- /* Calculate checksum of IP header */
- IPHeader->Checksum = (USHORT)
- ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
-}
-
-/* EOF */
reactos/drivers/net/afd/doc
diff -N simple_select.txt
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ simple_select.txt 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,47 @@
+
+
+
+ ActivePoll -> Timer, Dpc, Handles
+
+
+ FCB -> Polls Involved In ...
+
+
+What poll needs to do:
+ Accumulate:
+ for each fcb
+ If error is set, check error condition on fcb on entry
+ If writable is set, check fcb on entry for zero send content
+ If readable is set, check fcb has nonzero read content
+
+ If any handle was not valid, complete fail
+
+ If any of the above checks were true, complete success
+ Otherwise:
+ make an active poll object
+ for each fcb, make a poll entry
+ chain the poll entry to the fcb
+ set summary bits in fcb state for polling (what must be polled)
+ chain the active poll object to the device ext
+ set timer and dpc
+ pending
+
+complete select:
+ for each fcb
+ find the poll entry in the fcb and unchain it
+ rescan poll bits for this fcb
+ get irp from poll object, and deallocate poll object
+ complete irp
+
+select timeout:
+ Find the poll object in the device ext chain and unchain it
+ complete select with timeout
+
+fcb send complete and connect complete:
+ if no more send irps and send bit set in summary
+ find each poll entry with send bit set and complete select with (1) on it
+
+fcb recv complete:
+ if fcb has recv data and recv bit set in summary
+ find each poll entry with recv bit set and complete select with (1) on it
+
reactos/drivers/net/afd/include
diff -N tdi_proto.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tdi_proto.h 18 Jul 2004 22:49:17 -0000 1.2
@@ -0,0 +1,17 @@
+#ifndef _TDI_PROTO_H
+#define _TDI_PROTO_H
+
+NTSTATUS TdiConnect( PIRP *PendingIrp,
+ PFILE_OBJECT ConnectionObject,
+ PTRANSPORT_ADDRESS RemoteAddress,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext );
+
+NTSTATUS TdiOpenConnectionEndpointFile(PUNICODE_STRING DeviceName,
+ PHANDLE ConnectionHandle,
+ PFILE_OBJECT *ConnectionObject);
+
+NTSTATUS TdiCloseDevice(HANDLE Handle,
+ PFILE_OBJECT FileObject);
+
+#endif/*_TDI_PROTO_H*/
reactos/drivers/net/afd/include
diff -u -r1.18 -r1.19
--- afd.h 15 Jun 2004 02:56:13 -0000 1.18
+++ afd.h 18 Jul 2004 22:49:17 -0000 1.19
@@ -1,423 +1,287 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS Ancillary Function Driver
- * FILE: include/afd.h
- * PURPOSE: Main driver header
+/* $Id: afd.h,v 1.19 2004/07/18 22:49:17 arty Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: drivers/net/afd/include/afd.h
+ * PURPOSE: Ancillary functions driver -- constants and structures
+ * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
+ * UPDATE HISTORY:
+ * 20040630 Created
*/
-#ifndef __AFD_H
-#define __AFD_H
-#include <winsock2.h>
-#include <ddk/ntddk.h>
-#include <ddk/ntifs.h>
-#include <ddk/tdiinfo.h>
-#include <ddk/tdikrnl.h>
-#include <afd/shared.h>
-#include <debug.h>
-
-#define IP_MIB_STATS_ID 1
-#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
-
-/* Forward declarations */
-struct _AFDFCB;
-
-typedef struct _DEVICE_EXTENSION {
- PDEVICE_OBJECT StorageDevice;
- KSPIN_LOCK FCBListLock;
- LIST_ENTRY FCBListHead;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-/* Context Control Block structure */
-typedef struct _AFDCCB {
- struct _AFDFCB *FCB;
- LIST_ENTRY ListEntry;
- PFILE_OBJECT FileObject;
- ULONG Flags;
- LARGE_INTEGER CurrentByteOffset;
-} AFDCCB, *PAFDCCB;
-
-/* Flags for CCB structure */
-#define CCB_CLEANED 0x00000001
-
-typedef struct _FsdNTRequiredFCB {
- FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
- SECTION_OBJECT_POINTERS SectionObject;
- ERESOURCE MainResource;
- ERESOURCE PagingIoResource;
-} FsdNTRequiredFCB, *PFsdNTRequiredFCB;
-
-typedef struct _AFDFCB {
- FsdNTRequiredFCB NTRequiredFCB;
- LIST_ENTRY ListEntry;
- BOOL CommandChannel;
- PDEVICE_EXTENSION DeviceExt;
- SHARE_ACCESS ShareAccess;
- ULONG ReferenceCount;
- ULONG OpenHandleCount;
- HANDLE TdiAddressObjectHandle;
- PFILE_OBJECT TdiAddressObject;
- HANDLE TdiConnectionObjectHandle;
- PFILE_OBJECT TdiConnectionObject;
- LIST_ENTRY CCBListHead;
- INT AddressFamily;
- INT SocketType;
- INT Protocol;
- SOCKADDR SocketName;
- PVOID HelperContext;
- DWORD NotificationEvents;
- UNICODE_STRING TdiDeviceName;
- DWORD State;
- PVOID SendBuffer;
- LIST_ENTRY ReceiveQueue;
- KSPIN_LOCK ReceiveQueueLock;
- LIST_ENTRY ReadRequestQueue;
- LIST_ENTRY ListenRequestQueue;
- /* For WSAEventSelect() */
- WSANETWORKEVENTS NetworkEvents;
- PKEVENT EventObject;
-} AFDFCB, *PAFDFCB;
-
-/* Socket states */
-#define SOCKET_STATE_CREATED 0
-#define SOCKET_STATE_BOUND 1
-#define SOCKET_STATE_LISTENING 2
-#define SOCKET_STATE_CONNECTED 3
-
-typedef struct _AFD_BUFFER {
- LIST_ENTRY ListEntry;
- WSABUF Buffer;
- UINT Offset;
-} AFD_BUFFER, *PAFD_BUFFER;
-
-typedef struct _AFD_READ_REQUEST {
- LIST_ENTRY ListEntry;
- PIRP Irp;
- PFILE_REQUEST_RECVFROM RecvFromRequest;
- PFILE_REPLY_RECVFROM RecvFromReply;
-} AFD_READ_REQUEST, *PAFD_READ_REQUEST;
-
-typedef struct _AFD_LISTEN_REQUEST {
- LIST_ENTRY ListEntry;
- PAFDFCB Fcb;
- PTDI_CONNECTION_INFORMATION RequestConnectionInfo;
- IO_STATUS_BLOCK Iosb;
-} AFD_LISTEN_REQUEST, *PAFD_LISTEN_REQUEST;
-
-typedef struct IPSNMP_INFO {
- ULONG Forwarding;
- ULONG DefaultTTL;
- ULONG InReceives;
- ULONG InHdrErrors;
- ULONG InAddrErrors;
- ULONG ForwDatagrams;
- ULONG InUnknownProtos;
- ULONG InDiscards;
- ULONG InDelivers;
- ULONG OutRequests;
- ULONG RoutingDiscards;
- ULONG OutDiscards;
- ULONG OutNoRoutes;
- ULONG ReasmTimeout;
- ULONG ReasmReqds;
- ULONG ReasmOks;
- ULONG ReasmFails;
- ULONG FragOks;
- ULONG FragFails;
- ULONG FragCreates;
- ULONG NumIf;
- ULONG NumAddr;
- ULONG NumRoutes;
-} IPSNMP_INFO, *PIPSNMP_INFO;
-
-typedef struct IPADDR_ENTRY {
- ULONG Addr;
- ULONG Index;
- ULONG Mask;
- ULONG BcastAddr;
- ULONG ReasmSize;
- USHORT Context;
- USHORT Pad;
-} IPADDR_ENTRY, *PIPADDR_ENTRY;
-
-
-#define TL_INSTANCE 0
-
-/* IPv4 header format */
-typedef struct IPv4_HEADER {
- UCHAR VerIHL; /* 4-bit version, 4-bit Internet Header Length */
- UCHAR Tos; /* Type of Service */
- USHORT TotalLength; /* Total Length */
- USHORT Id; /* Identification */
- USHORT FlagsFragOfs; /* 3-bit Flags, 13-bit Fragment Offset */
- UCHAR Ttl; /* Time to Live */
- UCHAR Protocol; /* Protocol */
- USHORT Checksum; /* Header Checksum */
- ULONG SrcAddr; /* Source Address */
- ULONG DstAddr; /* Destination Address */
-} IPv4_HEADER, *PIPv4_HEADER;
-
-
-/* IOCTL codes */
-
-#define IOCTL_TCP_QUERY_INFORMATION_EX \
- CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)
-
-#define IOCTL_TCP_SET_INFORMATION_EX \
- CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-
-
-#ifdef i386
-
-/* DWORD network to host byte order conversion for i386 */
-#define DN2H(dw) \
- ((((dw) & 0xFF000000L) >> 24) | \
- (((dw) & 0x00FF0000L) >> 8) | \
- (((dw) & 0x0000FF00L) << 8) | \
- (((dw) & 0x000000FFL) << 24))
-
-/* DWORD host to network byte order conversion for i386 */
-#define DH2N(dw) \
- ((((dw) & 0xFF000000L) >> 24) | \
- (((dw) & 0x00FF0000L) >> 8) | \
- (((dw) & 0x0000FF00L) << 8) | \
- (((dw) & 0x000000FFL) << 24))
-
-/* WORD network to host order conversion for i386 */
-#define WN2H(w) \
- ((((w) & 0xFF00) >> 8) | \
- (((w) & 0x00FF) << 8))
-
-/* WORD host to network byte order conversion for i386 */
-#define WH2N(w) \
- ((((w) & 0xFF00) >> 8) | \
- (((w) & 0x00FF) << 8))
-
-#else /* i386 */
-
-/* DWORD network to host byte order conversion for other architectures */
-#define DN2H(dw) \
- (dw)
-
-/* DWORD host to network byte order conversion for other architectures */
-#define DH2N(dw) \
- (dw)
-
-/* WORD network to host order conversion for other architectures */
-#define WN2H(w) \
- (w)
-
-/* WORD host to network byte order conversion for other architectures */
-#define WH2N(w) \
- (w)
-
-#endif /* i386 */
-
-
-extern NPAGED_LOOKASIDE_LIST BufferLookasideList;
-extern NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
-extern NPAGED_LOOKASIDE_LIST ListenRequestLookasideList;
-
-/* Prototypes from dispatch.c */
-
-NTSTATUS AfdDispBind(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
-
-NTSTATUS AfdDispListen(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
-
-NTSTATUS AfdDispSendTo(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
-
-NTSTATUS AfdDispRecvFrom(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
-
-NTSTATUS AfdDispSelect(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
+#ifndef _AFD_H
+#define _AFD_H
-NTSTATUS AfdDispEventSelect(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
+#include <ntddk.h>
+#include <tdi.h>
+#include <tdikrnl.h>
+#include <tdiinfo.h>
+#include <string.h>
+#include <ndis.h>
+#include <shared.h>
-NTSTATUS AfdDispEnumNetworkEvents(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
+#ifndef _MSC_VER
+#include <rosrtl/string.h>
+#include <winsock2.h>
+#include <ddk/tdi.h>
+#include <ddk/ndis.h>
+#include <tcpmisc.h>
+#include <tcpioctl.h>
+#else
+#include <ntdef.h>
+#define STDCALL
+#endif
+
+#ifndef MIN
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#endif
+
+#define SOCKET_STATE_INVALID_TRANSITION ((DWORD)-1)
+#define SOCKET_STATE_CREATED 0
+#define SOCKET_STATE_BOUND 1
+#define SOCKET_STATE_CONNECTING 2
+#define SOCKET_STATE_CONNECTED 3
+#define SOCKET_STATE_LISTENING 4
+#define SOCKET_STATE_MASK 0x0000ffff
+#define SOCKET_STATE_LOCKED 0x40000000
+#define SOCKET_STATE_NEW 0x80000000
+#define SOCKET_STATE_CLOSED 0x00000100
+
+#define FUNCTION_CONNECT 0
+#define FUNCTION_RECV 1
+#define FUNCTION_RECV_DATAGRAM 2
+#define FUNCTION_SEND 3
+#define FUNCTION_CLOSE 4
+#define MAX_FUNCTIONS 5
+
+#define IN_FLIGHT_REQUESTS 3
+
+#define DEFAULT_SEND_WINDOW_SIZE 16384
+#define DEFAULT_RECEIVE_WINDOW_SIZE 16384
+
+#define SGID_CONNECTIONLESS 1 /* XXX Find this flag */
+
+typedef struct _AFD_MAPBUF {
+ PVOID BufferAddress;
+ PMDL Mdl;
+} AFD_MAPBUF, *PAFD_MAPBUF;
+
+typedef struct _AFD_DEVICE_EXTENSION {
+ PDEVICE_OBJECT DeviceObject;
+ LIST_ENTRY Polls;
+ KSPIN_LOCK Lock;
+} AFD_DEVICE_EXTENSION, *PAFD_DEVICE_EXTENSION;
+
+typedef struct _AFD_ACTIVE_POLL {
+ LIST_ENTRY ListEntry;
+ PIRP Irp;
+ PAFD_DEVICE_EXTENSION DeviceExt;
+ KDPC TimeoutDpc;
+ KTIMER Timer;
+} AFD_ACTIVE_POLL, *PAFD_ACTIVE_POLL;
+
+typedef struct _IRP_LIST {
+ LIST_ENTRY ListEntry;
+ PIRP Irp;
+} IRP_LIST, *PIRP_LIST;
+
+typedef struct _AFD_TDI_OBJECT {
+ PFILE_OBJECT Object;
+ HANDLE Handle;
+} AFD_TDI_OBJECT, *PAFD_TDI_OBJECT;
+
+typedef struct _AFD_IN_FLIGHT_REQUEST {
+ PIRP InFlightRequest;
+ IO_STATUS_BLOCK Iosb;
+ PTDI_CONNECTION_INFORMATION ConnectionInfo;
+} AFD_IN_FLIGHT_REQUEST, *PAFD_IN_FLIGHT_REQUEST;
+
+typedef struct _AFD_DATA_WINDOW {
+ PCHAR Window;
+ UINT BytesUsed, Size, Content;
+} AFD_DATA_WINDOW, *PAFD_DATA_WINDOW;
+
+typedef struct _AFD_STORED_DATAGRAM {
+ LIST_ENTRY ListEntry;
+ UINT Len;
+ PTA_ADDRESS Address;
+ CHAR Buffer[1];
+} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
+
+typedef struct _AFD_FCB {
+ BOOLEAN Locked;
+ UINT State, Flags;
+ KIRQL OldIrql;
+ UINT LockCount;
+ PVOID CurrentThread;
+ KSPIN_LOCK SpinLock;
+ PFILE_OBJECT FileObject;
+ PAFD_DEVICE_EXTENSION DeviceExt;
+ BOOLEAN DelayedAccept;
+ PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
+ PTDI_CONNECTION_INFORMATION AddressFrom;
+ AFD_TDI_OBJECT AddressFile, Connection;
+ AFD_IN_FLIGHT_REQUEST ListenIrp, ReceiveIrp, SendIrp;
+ AFD_DATA_WINDOW Send, Recv;
+ FAST_MUTEX Mutex;
+ KEVENT StateLockedEvent;
+ UNICODE_STRING TdiDeviceName;
+ PVOID Context;
+ DWORD PollState;
+ UINT ContextSize;
+ PIRP PendingTdiIrp;
+ LIST_ENTRY PendingIrpList[MAX_FUNCTIONS];
+ LIST_ENTRY DatagramList;
+} AFD_FCB, *PAFD_FCB;
+
+/* bind.c */
+
+NTSTATUS WarmSocketForBind( PAFD_FCB FCB );
+NTSTATUS STDCALL
+AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+/* connect.c */
+
+NTSTATUS WarmSocketForConnection( PAFD_FCB FCB );
+NTSTATUS STDCALL
+AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+/* context.c */
+
+NTSTATUS STDCALL
+AfdGetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp );
+NTSTATUS STDCALL
+AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp );
+
+/* info.c */
+
+NTSTATUS STDCALL
+AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp );
+
+/* listen.c */
+
+NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+/* lock.c */
+
+PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, BOOLEAN Write );
+VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count );
+UINT SocketAcquireStateLock( PAFD_FCB FCB );
+NTSTATUS DDKAPI UnlockAndMaybeComplete
+( PAFD_FCB FCB, NTSTATUS Status, PIRP Irp,
+ UINT Information,
+ PIO_COMPLETION_ROUTINE Completion,
+ BOOL ShouldUnlockIrp );
+VOID SocketStateUnlock( PAFD_FCB FCB );
+NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp );
+PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
+VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
+
+/* main.c */
-NTSTATUS AfdDispRecv(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
+VOID OskitDumpBuffer( PCHAR Buffer, UINT Len );
+NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function );
-NTSTATUS AfdDispSend(
- PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
+/* read.c */
-NTSTATUS AfdDispConnect(
+NTSTATUS DDKAPI ReceiveComplete
+( PDEVICE_OBJECT DeviceObject,
PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
+ PVOID Context );
-NTSTATUS AfdDispGetName(
+NTSTATUS DDKAPI PacketSocketRecvComplete
+( PDEVICE_OBJECT DeviceObject,
PIRP Irp,
- PIO_STACK_LOCATION IrpSp);
-
-/* Prototypes from event.c */
+ PVOID Context );
-NTSTATUS AfdRegisterEventHandlers(
- PAFDFCB FCB);
+NTSTATUS STDCALL
+AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp, BOOLEAN Short);
+NTSTATUS STDCALL
+AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp );
+
+/* select.c */
+
+NTSTATUS STDCALL
+AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp );
+VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceObject, PFILE_OBJECT FileObject );
-NTSTATUS AfdDeregisterEventHandlers(
- PAFDFCB FCB);
-
-/* Prototypes from opnclose.c */
-
-NTSTATUS STDCALL AfdCreate(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-
-NTSTATUS STDCALL AfdClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-
-/* Prototypes from rdwr.c */
-
-NTSTATUS AfdEventReceiveDatagramHandler(
- IN PVOID TdiEventContext,
- IN LONG SourceAddressLength,
- IN PVOID SourceAddress,
- IN LONG OptionsLength,
- IN PVOID Options,
- IN ULONG ReceiveDatagramFlags,
- IN ULONG BytesIndicated,
- IN ULONG BytesAvailable,
- OUT ULONG * BytesTaken,
- IN PVOID Tsdu,
- OUT PIRP * IoRequestPacket);
-
-NTSTATUS STDCALL AfdRead(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-
-NTSTATUS STDCALL AfdWrite(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp);
-
-/* Prototypes from routines.c */
-
-VOID DumpName(
- LPSOCKADDR Name);
-
-/* Requires caller to hold the recv queue lock */
-VOID TryToSatisfyRecvRequest( PAFDFCB FCB, BOOL Continuous );
-
-ULONG WSABufferSize(
- LPWSABUF Buffers,
- DWORD BufferCount);
-
-NTSTATUS MergeWSABuffers(
- LPWSABUF Buffers,
- DWORD BufferCount,
- PVOID Destination,
- ULONG MaxLength,
- PULONG BytesCopied);
-
-NTSTATUS FillWSABuffers(
- PAFDFCB FCB,
- LPWSABUF Buffers,
- DWORD BufferCount,
- PULONG BytesCopied,
- BOOL Continuous);
-
-VOID BuildIPv4Header(
- PIPv4_HEADER IPHeader,
- ULONG TotalSize,
- ULONG Protocol,
- PSOCKADDR SourceAddress,
- PSOCKADDR DestinationAddress);
-
-/* Prototypes from tdi.c */
-
-NTSTATUS TdiCloseDevice(
- HANDLE Handle,
- PFILE_OBJECT FileObject);
-
-NTSTATUS TdiOpenAddressFileIPv4(
- PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
- PHANDLE AddressHandle,
- PFILE_OBJECT *AddressObject);
+/* tdi.c */
NTSTATUS TdiOpenAddressFile(
- PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
- PHANDLE AddressHandle,
- PFILE_OBJECT *AddressObject);
-
-NTSTATUS TdiOpenConnectionEndpointFile(
- PUNICODE_STRING DeviceName,
- PHANDLE ConnectionHandle,
- PFILE_OBJECT *ConnectionObject);
-
-NTSTATUS TdiConnect(
- PFILE_OBJECT ConnectionObject,
- LPSOCKADDR RemoteAddress);
+ PUNICODE_STRING DeviceName,
+ PTRANSPORT_ADDRESS Name,
+ PHANDLE AddressHandle,
+ PFILE_OBJECT *AddressObject);
NTSTATUS TdiAssociateAddressFile(
HANDLE AddressHandle,
PFILE_OBJECT ConnectionObject);
-NTSTATUS TdiListen(
- PAFD_LISTEN_REQUEST Request,
+NTSTATUS TdiListen
+( PIRP *Irp,
+ PFILE_OBJECT ConnectionObject,
+ PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext);
+
+NTSTATUS TdiReceive
+( PIRP *Irp,
+ PFILE_OBJECT ConnectionObject,
+ USHORT Flags,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext);
+
+NTSTATUS TdiSend
+( PIRP *Irp,
+ PFILE_OBJECT ConnectionObject,
+ USHORT Flags,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);
-NTSTATUS TdiSetEventHandler(
- PFILE_OBJECT FileObject,
- LONG EventType,
- PVOID Handler,
- PVOID Context);
-
-NTSTATUS TdiQueryInformation(
- PFILE_OBJECT FileObject,
- LONG QueryType,
- PMDL MdlBuffer);
-
-NTSTATUS TdiQueryDeviceControl(
- PFILE_OBJECT FileObject,
- ULONG IoControlCode,
- PVOID InputBuffer,
- ULONG InputBufferLength,
- PVOID OutputBuffer,
- ULONG OutputBufferLength,
- PULONG Return);
-
-NTSTATUS TdiQueryInformationEx(
- PFILE_OBJECT FileObject,
- ULONG Entity,
- ULONG Instance,
- ULONG Class,
- ULONG Type,
- ULONG Id,
- PVOID OutputBuffer,
- PULONG OutputLength);
-
-NTSTATUS TdiQueryAddress(
- PFILE_OBJECT FileObject,
- PULONG Address);
-
-NTSTATUS TdiSend(
- PFILE_OBJECT TransportObject,
- PVOID Buffer,
- ULONG BufferSize);
+NTSTATUS TdiReceiveDatagram(
+ PIRP *Irp,
+ PFILE_OBJECT TransportObject,
+ USHORT Flags,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PTDI_CONNECTION_INFORMATION From,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext);
NTSTATUS TdiSendDatagram(
- PFILE_OBJECT TransportObject,
- LPSOCKADDR Address,
- PMDL Mdl,
- ULONG BufferSize);
-
-#endif /*__AFD_H */
+ PIRP *Irp,
+ PFILE_OBJECT TransportObject,
+ PCHAR Buffer,
+ UINT BufferLength,
+ PTDI_CONNECTION_INFORMATION To,
+ PIO_STATUS_BLOCK Iosb,
+ PIO_COMPLETION_ROUTINE CompletionRoutine,
+ PVOID CompletionContext);
+
+/* write.c */
+
+NTSTATUS STDCALL
+AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp, BOOLEAN Short);
+NTSTATUS STDCALL
+AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
-/* EOF */
+#endif/*_AFD_H*/
reactos/drivers/net/afd/include
diff -u -r1.1 -r1.2
--- tdiconn.h 7 Feb 2004 04:50:44 -0000 1.1
+++ tdiconn.h 18 Jul 2004 22:49:17 -0000 1.2
@@ -2,27 +2,30 @@
#define _TDICONN_H
#include <afd.h>
+#ifdef _MSC_VER
+#include <ntddtdi.h>
+#endif
typedef VOID *PTDI_CONNECTION_INFO_PAIR;
-DWORD TdiAddressSizeFromType( ULONG Type );
-DWORD TdiAddressSizeFromName( LPSOCKADDR Name );
-VOID TdiBuildAddressIPv4( PTA_IP_ADDRESS Address,
- LPSOCKADDR Name );
-NTSTATUS TdiBuildAddress( PTA_ADDRESS Address,
- LPSOCKADDR Name );
-NTSTATUS TdiBuildName( LPSOCKADDR Name,
- PTA_ADDRESS Address );
+PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress );
+UINT TaLengthOfAddress( PTA_ADDRESS Addr );
+UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr );
+VOID TaCopyAddressInPlace( PTA_ADDRESS Target, PTA_ADDRESS Source );
+VOID TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target,
+ PTRANSPORT_ADDRESS Source );
+UINT TdiAddressSizeFromType( UINT Type );
+UINT TdiAddressSizeFromName( PTRANSPORT_ADDRESS Name );
NTSTATUS TdiBuildConnectionInfoInPlace
-( PTDI_CONNECTION_INFORMATION ConnInfo, LPSOCKADDR Name );
+( PTDI_CONNECTION_INFORMATION ConnInfo, PTA_ADDRESS Name );
NTSTATUS TdiBuildConnectionInfo
-( PTDI_CONNECTION_INFORMATION *ConnectionInfo, LPSOCKADDR Name );
+( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTA_ADDRESS Name );
NTSTATUS TdiBuildNullConnectionInfoToPlace
( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type );
NTSTATUS TdiBuildNullConnectionInfo
( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type );
NTSTATUS TdiBuildConnectionInfoPair
-( PTDI_CONNECTION_INFO_PAIR ConnectionInfo, LPSOCKADDR From, LPSOCKADDR To );
+( PTDI_CONNECTION_INFO_PAIR ConnectionInfo, PTA_ADDRESS From, PTA_ADDRESS To );
PTA_ADDRESS TdiGetRemoteAddress( PTDI_CONNECTION_INFORMATION TdiConn );
#endif/*_TDICONN_H*/
reactos/lib/msafd
diff -u -r1.14 -r1.15
--- makefile 9 Jun 2004 18:11:39 -0000 1.14
+++ makefile 18 Jul 2004 22:49:17 -0000 1.15
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.14 2004/06/09 18:11:39 arty Exp $
+# $Id: makefile,v 1.15 2004/07/18 22:49:17 arty Exp $
PATH_TO_TOP = ../..
@@ -8,7 +8,7 @@
TARGET_BASE = $(TARGET_BASE_LIB_MSAFD)
-TARGET_SDKLIBS = ntdll.a kernel32.a
+TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a
TARGET_CFLAGS = \
-I./include \
reactos/lib/msafd
diff -u -r1.2 -r1.3
--- msafd.def 26 Aug 2003 12:28:53 -0000 1.2
+++ msafd.def 18 Jul 2004 22:49:17 -0000 1.3
@@ -3,6 +3,6 @@
LIBRARY msafd.dll
EXPORTS
-WSPStartup@76
+WSPStartup=_WSPStartup@76
; EOF
reactos/lib/msafd/include
diff -u -r1.1 -r1.2
--- helpers.h 14 Jan 2001 17:37:01 -0000 1.1
+++ helpers.h 18 Jul 2004 22:49:17 -0000 1.2
@@ -9,53 +9,64 @@
#include <msafd.h>
-typedef struct _WSHELPER_DLL_ENTRIES {
- PWSH_ADDRESS_TO_STRING lpWSHAddressToString;
- PWSH_ENUM_PROTOCOLS lpWSHEnumProtocols;
- PWSH_GET_BROADCAST_SOCKADDR lpWSHGetBroadcastSockaddr;
- PWSH_GET_PROVIDER_GUID lpWSHGetProviderGuid;
- PWSH_GET_SOCKADDR_TYPE lpWSHGetSockaddrType;
- PWSH_GET_SOCKET_INFORMATION lpWSHGetSocketInformation;
- PWSH_GET_WILDCARD_SOCKEADDR lpWSHGetWildcardSockaddr;
- PWSH_GET_WINSOCK_MAPPING lpWSHGetWinsockMapping;
- PWSH_GET_WSAPROTOCOL_INFO lpWSHGetWSAProtocolInfo;
- PWSH_IOCTL lpWSHIoctl;
- PWSH_JOIN_LEAF lpWSHJoinLeaf;
- PWSH_NOTIFY lpWSHNotify;
- PWSH_OPEN_SOCKET lpWSHOpenSocket;
- PWSH_OPEN_SOCKET2 lpWSHOpenSocket2;
- PWSH_SET_SOCKET_INFORMATION lpWSHSetSocketInformation;
- PWSH_STRING_TO_ADDRESS lpWSHStringToAddress;
-} WSHELPER_DLL_ENTRIES, *PWSHELPER_DLL_ENTRIES;
-
-typedef struct _WSHELPER_DLL {
- LIST_ENTRY ListEntry;
- CRITICAL_SECTION Lock;
- WCHAR LibraryName[MAX_PATH];
- HMODULE hModule;
- WSHELPER_DLL_ENTRIES EntryTable;
- PWINSOCK_MAPPING Mapping;
-} WSHELPER_DLL, *PWSHELPER_DLL;
-
-
-PWSHELPER_DLL CreateHelperDLL(
- LPWSTR LibraryName);
-
-INT DestroyHelperDLL(
- PWSHELPER_DLL HelperDLL);
-
-PWSHELPER_DLL LocateHelperDLL(
- LPWSAPROTOCOL_INFOW lpProtocolInfo);
-
-INT LoadHelperDLL(
- PWSHELPER_DLL HelperDLL);
-
-INT UnloadHelperDLL(
- PWSHELPER_DLL HelperDLL);
-
-VOID CreateHelperDLLDatabase(VOID);
-
-VOID DestroyHelperDLLDatabase(VOID);
+typedef struct _HELPER_DATA {
+ LIST_ENTRY Helpers;
+ LONG RefCount;
+ HANDLE hInstance;
+ INT MinWSAddressLength;
+ INT MaxWSAddressLength;
+ INT MinTDIAddressLength;
+ INT MaxTDIAddressLength;
+ BOOLEAN UseDelayedAcceptance;
+ PWINSOCK_MAPPING Mapping;
+ PWSH_OPEN_SOCKET WSHOpenSocket;
+ PWSH_OPEN_SOCKET2 WSHOpenSocket2;
+ PWSH_JOIN_LEAF WSHJoinLeaf;
+ PWSH_NOTIFY WSHNotify;
+ PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation;
+ PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation;
+ PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType;
+ PWSH_GET_WILDCARD_SOCKEADDR WSHGetWildcardSockaddr;
+ PWSH_GET_BROADCAST_SOCKADDR WSHGetBroadcastSockaddr;
+ PWSH_ADDRESS_TO_STRING WSHAddressToString;
+ PWSH_STRING_TO_ADDRESS WSHStringToAddress;
+ PWSH_IOCTL WSHIoctl;
+ WCHAR TransportName[1];
+} HELPER_DATA, *PHELPER_DATA;
+
+int SockLoadHelperDll(
+ PWSTR TransportName,
+ PWINSOCK_MAPPING Mapping,
+ PHELPER_DATA *HelperDllData
+);
+
+int SockLoadTransportMapping(
+ PWSTR TransportName,
+ PWINSOCK_MAPPING *Mapping
+);
+
+int SockLoadTransportList(
+ PWSTR *TransportList
+);
+
+BOOL SockIsTripleInMapping(
+ PWINSOCK_MAPPING Mapping,
+ INT AddressFamily,
+ INT SocketType,
+ INT Protocol
+);
+
+int SockGetTdiName(
+ PINT AddressFamily,
+ PINT SocketType,
+ PINT Protocol,
+ GROUP Group,
+ DWORD Flags,
+ PUNICODE_STRING TransportName,
+ PVOID *HelperDllContext,
+ PHELPER_DATA *HelperDllData,
+ PDWORD Events
+);
#endif /* __HELPERS_H */
reactos/lib/msafd/include
diff -u -r1.7 -r1.8
--- msafd.h 4 Mar 2004 20:45:39 -0000 1.7
+++ msafd.h 18 Jul 2004 22:49:17 -0000 1.8
@@ -11,23 +11,102 @@
#include <windows.h>
#include <ddk/ntddk.h>
#include <ddk/ntifs.h>
-#include <wsahelp.h>
+#include <wsahelp.h> /* comment for msvc */
+//#include "C:\Programming\ReactOS\reactos\w32api\include\wsahelp.h" uncomment for MSVC
#include <winsock2.h>
#include <ws2spi.h>
-#include <ddk/tdi.h>
+//#include "C:\Programming\ReactOS\reactos\w32api\include\ddk\tdi.h" uncomment for MSVC
+#include <ddk/tdi.h> /* comment for msvc */
#include <afd/shared.h>
+#include <helpers.h>
#include <debug.h>
-/*typedef _MSAFD_LISTEN_REQUEST
-{
- LIST_ENTRY ListEntry;
- HANDLE Socket;
-} MSAFD_LISTEN_REQUEST, *PMSAFD_LISTEN_REQUEST;*/
-
-
extern HANDLE GlobalHeap;
extern WSPUPCALLTABLE Upcalls;
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
+extern LIST_ENTRY SockHelpersListHead;
+extern HANDLE SockEvent;
+
+typedef enum _SOCKET_STATE {
+ SocketOpen,
+ SocketBound,
+ SocketBoundUdp,
+ SocketConnected,
+ SocketClosed
+} SOCKET_STATE, *PSOCKET_STATE;
+
+typedef struct _SOCK_SHARED_INFO {
+ SOCKET_STATE State;
+ INT AddressFamily;
+ INT SocketType;
+ INT Protocol;
+ INT SizeOfLocalAddress;
+ INT SizeOfRemoteAddress;
+ ULONG LingerData;
+ ULONG SendTimeout;
+ ULONG RecvTimeout;
+ ULONG SizeOfRecvBuffer;
+ ULONG SizeOfSendBuffer;
+ struct {
+ BOOLEAN Listening:1;
+ BOOLEAN Broadcast:1;
+ BOOLEAN Debug:1;
+ BOOLEAN OobInline:1;
+ BOOLEAN ReuseAddresses:1;
+ BOOLEAN ExclusiveAddressUse:1;
+ BOOLEAN NonBlocking:1;
+ BOOLEAN DontUseWildcard:1;
+ BOOLEAN ReceiveShutdown:1;
+ BOOLEAN SendShutdown:1;
+ BOOLEAN UseDelayedAcceptance:1;
+ BOOLEAN UseSAN:1;
+ }; // Flags
+ DWORD CreateFlags;
+ DWORD CatalogEntryId;
+ DWORD ServiceFlags1;
+ DWORD ProviderFlags;
+ GROUP GroupID;
+ DWORD GroupType;
+ INT GroupPriority;
+ INT SocketLastError;
+ HWND hWnd;
+ LONG Unknown;
+ DWORD SequenceNumber;
+ UINT wMsg;
+ LONG Event;
+ LONG DisabledEvents;
+} SOCK_SHARED_INFO, *PSOCK_SHARED_INFO;
+
+typedef struct _SOCKET_INFORMATION {
+ ULONG RefCount;
+ SOCKET Handle;
+ SOCK_SHARED_INFO SharedData;
+ DWORD HelperEvents;
+ PHELPER_DATA HelperData;
+ PVOID HelperContext;
+ PSOCKADDR LocalAddress;
+ PSOCKADDR RemoteAddress;
+ HANDLE TdiAddressHandle;
+ HANDLE TdiConnectionHandle;
+ PVOID AsyncData;
+ HANDLE EventObject;
+ LONG NetworkEvents;
+ CRITICAL_SECTION Lock;
+ PVOID SanData;
+ BOOL TrySAN;
+ SOCKADDR WSLocalAddress;
+ SOCKADDR WSRemoteAddress;
+} SOCKET_INFORMATION, *PSOCKET_INFORMATION;
+
+
+typedef struct _SOCKET_CONTEXT {
+ SOCK_SHARED_INFO SharedData;
+ ULONG SizeOfHelperData;
+ ULONG Padding;
+ SOCKADDR LocalAddress;
+ SOCKADDR RemoteAddress;
+ /* Plus Helper Data */
+} SOCKET_CONTEXT, *PSOCKET_CONTEXT;
SOCKET
WSPAPI
@@ -314,6 +393,28 @@
IN OUT LPINT lpAddressLength,
OUT LPINT lpErrno);
+
+PSOCKET_INFORMATION GetSocketStructure(
+ SOCKET Handle
+);
+
+int GetSocketInformation(
+ PSOCKET_INFORMATION Socket,
+ ULONG AfdInformationClass,
+ PULONG Ulong OPTIONAL,
+ PLARGE_INTEGER LargeInteger OPTIONAL
+);
+
+int SetSocketInformation(
+ PSOCKET_INFORMATION Socket,
+ ULONG AfdInformationClass,
+ PULONG Ulong OPTIONAL,
+ PLARGE_INTEGER LargeInteger OPTIONAL
+);
+
+int CreateContext(
+ PSOCKET_INFORMATION Socket
+);
#endif /* __MSAFD_H */
/* EOF */
reactos/lib/msafd/misc
diff -u -r1.13 -r1.14
--- dllmain.c 9 Jun 2004 18:11:39 -0000 1.13
+++ dllmain.c 18 Jul 2004 22:49:17 -0000 1.14
@@ -4,8 +4,10 @@
* FILE: misc/dllmain.c
* PURPOSE: DLL entry point
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Alex Ionescu (alex@relsoft.net)
* REVISIONS:
* CSH 01/09-2000 Created
+ * Alex 16/07/2004 - Complete Rewrite
*/
#include <string.h>
#include <msafd.h>
@@ -13,146 +15,30 @@
#include <rosrtl/string.h>
#ifdef DBG
-
-/* See debug.h for debug/trace constants */
-//DWORD DebugTraceLevel = MIN_TRACE;
DWORD DebugTraceLevel = DEBUG_ULTRA;
-
#endif /* DBG */
/* To make the linker happy */
VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
-/* FIXME: Protect me */
-static LIST_ENTRY MsAfdListenRequests; /* Queue of listen reqests */
-
-
-HANDLE GlobalHeap;
-WSPUPCALLTABLE Upcalls;
-LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
-CRITICAL_SECTION InitCriticalSection;
-DWORD StartupCount = 0;
-HANDLE CommandChannel;
-
-
-NTSTATUS OpenSocket(
- SOCKET *Socket,
- INT AddressFamily,
- INT SocketType,
- INT Protocol,
- PVOID HelperContext,
- DWORD NotificationEvents,
- PUNICODE_STRING TdiDeviceName)
-/*
- * FUNCTION: Opens a socket
- * ARGUMENTS:
- * Socket = Address of buffer to place socket descriptor
- * AddressFamily = Address family
- * SocketType = Type of socket
- * Protocol = Protocol type
- * HelperContext = Pointer to context information for helper DLL
- * NotificationEvents = Events for which helper DLL is to be notified
- * TdiDeviceName = Pointer to name of TDI device to use
- * RETURNS:
- * Status of operation
- */
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- PAFD_SOCKET_INFORMATION SocketInfo;
- PFILE_FULL_EA_INFORMATION EaInfo;
- UNICODE_STRING DeviceName;
- IO_STATUS_BLOCK Iosb;
- HANDLE FileHandle;
- NTSTATUS Status;
- ULONG EaLength;
- ULONG EaShort;
-
- AFD_DbgPrint(MAX_TRACE, ("Socket (0x%X) TdiDeviceName (%wZ)\n",
- Socket, TdiDeviceName));
-
- AFD_DbgPrint(MAX_TRACE, ("Socket2 (0x%X) TdiDeviceName (%S)\n",
- Socket, TdiDeviceName->Buffer));
-
- EaShort = sizeof(FILE_FULL_EA_INFORMATION) +
- AFD_SOCKET_LENGTH +
- sizeof(AFD_SOCKET_INFORMATION);
-
- EaLength = EaShort + TdiDeviceName->Length + sizeof(WCHAR);
+HANDLE GlobalHeap;
+WSPUPCALLTABLE Upcalls;
+LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
+HANDLE SockEvent;
+ULONG SocketCount;
+PSOCKET_INFORMATION *Sockets = NULL;
+LIST_ENTRY SockHelpersListHead = {NULL};
- EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength);
- if (!EaInfo) {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlZeroMemory(EaInfo, EaLength);
- EaInfo->EaNameLength = AFD_SOCKET_LENGTH;
- RtlCopyMemory(EaInfo->EaName,
- AfdSocket,
- AFD_SOCKET_LENGTH);
- EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION);
-
- SocketInfo = (PAFD_SOCKET_INFORMATION)((ULONG_PTR)EaInfo->EaName + AFD_SOCKET_LENGTH);
- SocketInfo->CommandChannel = FALSE;
- SocketInfo->AddressFamily = AddressFamily;
- SocketInfo->SocketType = SocketType;
- SocketInfo->Protocol = Protocol;
- SocketInfo->HelperContext = HelperContext;
- SocketInfo->NotificationEvents = NotificationEvents;
- /* Zeroed above so initialized to a wildcard address if a raw socket */
- SocketInfo->Name.sa_family = AddressFamily;
-
- /* Store TDI device name last in buffer */
- SocketInfo->TdiDeviceName.Buffer = (PWCHAR)(EaInfo + EaShort);
- SocketInfo->TdiDeviceName.MaximumLength = TdiDeviceName->Length + sizeof(WCHAR);
- RtlCopyUnicodeString(&SocketInfo->TdiDeviceName, TdiDeviceName);
-
- AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) EaLength is (%d).\n", (UINT)EaInfo, (INT)EaLength));
-
- RtlRosInitUnicodeStringFromLiteral(&DeviceName, L"\\Device\\Afd");
- InitializeObjectAttributes(
- &ObjectAttributes,
- &DeviceName,
- 0,
- NULL,
- NULL);
-
- Status = ZwCreateFile(
- &FileHandle,
- FILE_GENERIC_READ | FILE_GENERIC_WRITE,
- &ObjectAttributes,
- &Iosb,
- NULL,
- 0,
- 0,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_ALERT,
- EaInfo,
- EaLength);
-
- HeapFree(GlobalHeap, 0, EaInfo);
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n",
- (UINT)Status));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- *Socket = (SOCKET)FileHandle;
-
- return STATUS_SUCCESS;
-}
-
-
-SOCKET
-WSPAPI
+SOCKET
+WSPAPI
WSPSocket(
- IN INT af,
- IN INT type,
- IN INT protocol,
- IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
- IN GROUP g,
- IN DWORD dwFlags,
- OUT LPINT lpErrno)
+ int AddressFamily,
+ int SocketType,
+ int Protocol,
+ LPWSAPROTOCOL_INFOW lpProtocolInfo,
+ GROUP g,
+ DWORD dwFlags,
+ LPINT lpErrno)
/*
* FUNCTION: Creates a new socket
* ARGUMENTS:
@@ -167,99 +53,200 @@
* Created socket, or INVALID_SOCKET if it could not be created
*/
{
- WSAPROTOCOL_INFOW ProtocolInfo;
- UNICODE_STRING TdiDeviceName;
- DWORD NotificationEvents;
- PWSHELPER_DLL HelperDLL;
- PVOID HelperContext;
- INT AddressFamily;
- NTSTATUS NtStatus;
- INT SocketType;
- SOCKET Socket2;
- SOCKET Socket;
- INT Protocol;
- INT Status;
-
- AFD_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
- af, type, protocol));
-
- if (!lpProtocolInfo) {
- lpProtocolInfo = &ProtocolInfo;
- ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW));
-
- ProtocolInfo.iAddressFamily = af;
- ProtocolInfo.iSocketType = type;
- ProtocolInfo.iProtocol = protocol;
- }
+ OBJECT_ATTRIBUTES Object;
+ IO_STATUS_BLOCK IOSB;
+ USHORT SizeOfPacket;
+ ULONG SizeOfEA;
+ PAFD_CREATE_PACKET AfdPacket;
+ HANDLE Sock;
+ PSOCKET_INFORMATION Socket = NULL;
+ PFILE_FULL_EA_INFORMATION EABuffer = NULL;
+ PHELPER_DATA HelperData;
+ PVOID HelperDLLContext;
+ DWORD HelperEvents;
+ DWORD IOOptions;
+ UNICODE_STRING TransportName;
+ UNICODE_STRING DevName;
+ LARGE_INTEGER GroupData;
+ INT Status;
+
+ AFD_DbgPrint(MAX_TRACE, ("Creating Socket, getting TDI Name\n"));
+ AFD_DbgPrint(MAX_TRACE, ("AddressFamily (%d) SocketType (%d) Protocol (%d).\n",
+ AddressFamily, SocketType, Protocol));
+
+ /* Get Helper Data and Transport */
+ Status = SockGetTdiName (&AddressFamily,
+ &SocketType,
+ &Protocol,
+ g,
+ dwFlags,
+ &TransportName,
+ &HelperDLLContext,
+ &HelperData,
+ &HelperEvents);
+
+ /* Check for error */
+ if (Status != NO_ERROR) {
+ goto error;
+ }
- HelperDLL = LocateHelperDLL(lpProtocolInfo);
- if (!HelperDLL) {
- *lpErrno = WSAEAFNOSUPPORT;
- return INVALID_SOCKET;
- }
+ /* AFD Device Name */
+ RtlInitUnicodeString(&DevName, L"\\Device\\Afd\\Endpoint");
- AddressFamily = lpProtocolInfo->iAddressFamily;
- SocketType = lpProtocolInfo->iSocketType;
- Protocol = lpProtocolInfo->iProtocol;
-
- /* The OPTIONAL export WSHOpenSocket2 supersedes WSHOpenSocket */
- if (HelperDLL->EntryTable.lpWSHOpenSocket2)
- {
- Status = HelperDLL->EntryTable.lpWSHOpenSocket2(
- &AddressFamily,
- &SocketType,
- &Protocol,
- 0,
- 0,
- &TdiDeviceName,
- &HelperContext,
- &NotificationEvents);
- }
- else
- {
- Status = HelperDLL->EntryTable.lpWSHOpenSocket(
- &AddressFamily,
- &SocketType,
- &Protocol,
- &TdiDeviceName,
- &HelperContext,
- &NotificationEvents);
- }
-
- if (Status != NO_ERROR) {
- AFD_DbgPrint(MAX_TRACE, ("WinSock Helper DLL failed (0x%X).\n", Status));
- *lpErrno = Status;
- return INVALID_SOCKET;
- }
+ /* Set Socket Data */
+ Socket = HeapAlloc(GlobalHeap, 0, sizeof(*Socket));
+ RtlZeroMemory(Socket, sizeof(*Socket));
+ Socket->RefCount = 2;
+ Socket->Handle = -1;
+ Socket->SharedData.State = SocketOpen;
+ Socket->SharedData.AddressFamily = AddressFamily;
+ Socket->SharedData.SocketType = SocketType;
+ Socket->SharedData.Protocol = Protocol;
+ Socket->HelperContext = HelperDLLContext;
+ Socket->HelperData = HelperData;
+ Socket->HelperEvents = HelperEvents;
+ Socket->LocalAddress = &Socket->WSLocalAddress;
+ Socket->SharedData.SizeOfLocalAddress = HelperData->MaxWSAddressLength;
+ Socket->RemoteAddress = &Socket->WSRemoteAddress;
+ Socket->SharedData.SizeOfRemoteAddress = HelperData->MaxWSAddressLength;
+ Socket->SharedData.UseDelayedAcceptance = HelperData->UseDelayedAcceptance;
+ Socket->SharedData.CreateFlags = dwFlags;
+ Socket->SharedData.CatalogEntryId = lpProtocolInfo->dwCatalogEntryId;
+ Socket->SharedData.ServiceFlags1 = lpProtocolInfo->dwServiceFlags1;
+ Socket->SharedData.ProviderFlags = lpProtocolInfo->dwProviderFlags;
+ Socket->SharedData.GroupID = g;
+ Socket->SharedData.GroupType = 0;
+ Socket->SharedData.UseSAN = FALSE;
+ Socket->SanData = NULL;
+
+ /* Packet Size */
+ SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR);
+
+ /* EA Size */
+ SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH;
+
+ /* Set up EA Buffer */
+ EABuffer = HeapAlloc(GlobalHeap, 0, (SIZE_T)&SizeOfEA);
+ EABuffer->NextEntryOffset = 0;
+ EABuffer->Flags = 0;
+ EABuffer->EaNameLength = AFD_PACKET_COMMAND_LENGTH;
+ RtlCopyMemory (EABuffer->EaName,
+ AfdCommand,
+ AFD_PACKET_COMMAND_LENGTH + 1);
+ EABuffer->EaValueLength = SizeOfPacket;
+
+ /* Set up AFD Packet */
+ AfdPacket = (PAFD_CREATE_PACKET)(EABuffer->EaName + EABuffer->EaNameLength + 1);
+ AfdPacket->SizeOfTransportName = TransportName.Length;
+ RtlCopyMemory (AfdPacket->TransportName,
+ TransportName.Buffer,
+ TransportName.Length + sizeof(WCHAR));
+ AfdPacket->GroupID = g;
+
+ /* Set up Endpoint Flags */
+ if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECTIONLESS) != 0) {
+ if ((SocketType != SOCK_DGRAM) && (SocketType != SOCK_RAW)) {
+ goto error; /* Only RAW or UDP can be Connectionless */
+ }
+ AfdPacket->EndpointFlags |= AFD_ENDPOINT_CONNECTIONLESS;
+ }
+
+ if ((Socket->SharedData.ServiceFlags1 & XP1_MESSAGE_ORIENTED) != 0) {
+ if (SocketType == SOCK_STREAM) {
+ if ((Socket->SharedData.ServiceFlags1 & XP1_PSEUDO_STREAM) == 0) {
+ goto error; /* The Provider doesn't actually support Message Oriented Streams */
+ }
+ }
+ AfdPacket->EndpointFlags |= AFD_ENDPOINT_MESSAGE_ORIENTED;
+ }
- NtStatus = OpenSocket(&Socket,
- AddressFamily,
- SocketType,
- Protocol,
- HelperContext,
- NotificationEvents,
- &TdiDeviceName);
-
- RtlFreeUnicodeString(&TdiDeviceName);
- if (!NT_SUCCESS(NtStatus)) {
- *lpErrno = RtlNtStatusToDosError(Status);
- return INVALID_SOCKET;
- }
+ if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW;
- /* FIXME: Assumes catalog entry id to be 1 */
- Socket2 = Upcalls.lpWPUModifyIFSHandle(1, Socket, lpErrno);
+ if (dwFlags & (WSA_FLAG_MULTIPOINT_C_ROOT |
+ WSA_FLAG_MULTIPOINT_C_LEAF |
+ WSA_FLAG_MULTIPOINT_D_ROOT |
+ WSA_FLAG_MULTIPOINT_D_LEAF)) {
+ if ((Socket->SharedData.ServiceFlags1 & XP1_SUPPORT_MULTIPOINT) == 0) {
+ goto error; /* The Provider doesn't actually support Multipoint */
+ }
+ AfdPacket->EndpointFlags |= AFD_ENDPOINT_MULTIPOINT;
+ if (dwFlags & WSA_FLAG_MULTIPOINT_C_ROOT) {
+ if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) == 0)
+ || ((dwFlags & WSA_FLAG_MULTIPOINT_C_LEAF) != 0)) {
+ goto error; /* The Provider doesn't support Control Planes, or you already gave a leaf */
+ }
+ AfdPacket->EndpointFlags |= AFD_ENDPOINT_C_ROOT;
+ }
+ if (dwFlags & WSA_FLAG_MULTIPOINT_D_ROOT) {
+ if (((Socket->SharedData.ServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE) == 0)
+ || ((dwFlags & WSA_FLAG_MULTIPOINT_D_LEAF) != 0)) {
+ goto error; /* The Provider doesn't support Data Planes, or you already gave a leaf */
+ }
+ AfdPacket->EndpointFlags |= AFD_ENDPOINT_D_ROOT;
+ }
+ }
- if (Socket2 == INVALID_SOCKET) {
- /* FIXME: Cleanup */
- AFD_DbgPrint(MIN_TRACE, ("FIXME: Cleanup.\n"));
- return INVALID_SOCKET;
- }
+ /* Set up Object Attributes */
+ InitializeObjectAttributes (&Object,
+ &DevName,
+ OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
+ 0,
+ 0);
+
+ /* Set IO Flag */
+ if ((dwFlags & WSA_FLAG_OVERLAPPED) == 0) IOOptions = FILE_SYNCHRONOUS_IO_NONALERT;
+
+ /* Create the Socket */
+ ZwCreateFile(&Sock,
+ GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
+ &Object,
+ &IOSB,
+ NULL,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_OPEN_IF,
+ IOOptions,
+ EABuffer,
+ SizeOfEA);
+
+ /* Save Handle */
+ Socket->Handle = (SOCKET)Sock;
+
+ /* Save Group Info */
+ if (g != 0) {
+ GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, 0, &GroupData);
- *lpErrno = NO_ERROR;
+ Socket->SharedData.GroupID = GroupData.u.LowPart;
+ Socket->SharedData.GroupType = GroupData.u.HighPart;
+ }
+
+ /* Get Window Sizes and Save them */
+ GetSocketInformation (Socket,
+ AFD_INFO_SEND_WINDOW_SIZE,
+ &Socket->SharedData.SizeOfSendBuffer,
+ NULL);
+ GetSocketInformation (Socket,
+ AFD_INFO_RECEIVE_WINDOW_SIZE,
+ &Socket->SharedData.SizeOfRecvBuffer,
+ NULL);
+
+ /* Save in Process Sockets List */
+ Sockets[SocketCount] = Socket;
+ SocketCount ++;
+
+ /* Create the Socket Context */
+ CreateContext(Socket);
+
+ /* Notify Winsock */
+ Upcalls.lpWPUModifyIFSHandle(1, (SOCKET)Sock, lpErrno);
- AFD_DbgPrint(MID_TRACE, ("Returning socket descriptor (0x%X).\n", Socket2));
+ /* Return Socket Handle */
+ return (SOCKET)Sock;
- return Socket2;
+error:
+ AFD_DbgPrint(MID_TRACE,("Ending\n"));
+
+ return 0;
}
@@ -277,29 +264,17 @@
* NO_ERROR, or SOCKET_ERROR if the socket could not be closed
*/
{
- NTSTATUS Status;
-
- AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
-
- Status = NtClose((HANDLE)s);
-
- if (NT_SUCCESS(Status)) {
- *lpErrno = NO_ERROR;
- return NO_ERROR;
- }
-
- *lpErrno = WSAENOTSOCK;
- return SOCKET_ERROR;
+ return 0;
}
INT
WSPAPI
WSPBind(
- IN SOCKET s,
- IN CONST LPSOCKADDR name,
- IN INT namelen,
- OUT LPINT lpErrno)
+ SOCKET Handle,
+ struct sockaddr *SocketAddress,
+ int SocketAddressLength,
+ LPINT lpErrno)
/*
* FUNCTION: Associates a local address with a socket
* ARGUMENTS:
@@ -311,340 +286,616 @@
* 0, or SOCKET_ERROR if the socket could not be bound
*/
{
- FILE_REQUEST_BIND Request;
- FILE_REPLY_BIND Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
-
- AFD_DbgPrint(MAX_TRACE, ("s (0x%X) name (0x%X) namelen (%d).\n", s, name, namelen));
-
- RtlCopyMemory(&Request.Name, name, sizeof(SOCKADDR));
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_BIND,
- &Request,
- sizeof(FILE_REQUEST_BIND),
- &Reply,
- sizeof(FILE_REPLY_BIND));
- if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- *lpErrno = Reply.Status;
- return SOCKET_ERROR;
+ IO_STATUS_BLOCK IOSB;
+ PAFD_BIND_DATA BindData;
+ PSOCKET_INFORMATION Socket = NULL;
+ NTSTATUS Status;
+ UCHAR BindBuffer[0x1A];
+ SOCKADDR_INFO SocketInfo;
+
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+
+ /* Dynamic Structure...ugh */
+ BindData = (PAFD_BIND_DATA)BindBuffer;
+
+ /* Set up Address in TDI Format */
+ BindData->Address.TAAddressCount = 1;
+ BindData->Address.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
+ RtlCopyMemory (&BindData->Address.Address[0].AddressType,
+ SocketAddress,
+ SocketAddressLength);
+
+ /* Get Address Information */
+ Socket->HelperData->WSHGetSockaddrType ((PSOCKADDR)SocketAddress,
+ SocketAddressLength,
+ &SocketInfo);
+
+ /* Set the Share Type */
+ if (Socket->SharedData.ExclusiveAddressUse) {
+ BindData->ShareType = AFD_SHARE_EXCLUSIVE;
+ }
+ else if (SocketInfo.EndpointInfo == SockaddrEndpointInfoWildcard) {
+ BindData->ShareType = AFD_SHARE_WILDCARD;
+ }
+ else if (Socket->SharedData.ReuseAddresses) {
+ BindData->ShareType = AFD_SHARE_REUSE;
+ } else {
+ BindData->ShareType = AFD_SHARE_UNIQUE;
}
- return 0;
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
+ SockEvent,
+ NULL,
+ NULL,
+ &IOSB,
+ IOCTL_AFD_BIND,
+ BindData,
+ 0xA + Socket->SharedData.SizeOfLocalAddress, /* Can't figure out a way to calculate this in C*/
+ BindData,
+ 0xA + Socket->SharedData.SizeOfLocalAddress); /* Can't figure out a way to calculate this C */
+
+ /* Set up Socket Data */
+ Socket->SharedData.State = SocketBound;
+ Socket->TdiAddressHandle = (HANDLE)IOSB.Information;
+
+ return 0;
}
-INT
+int
WSPAPI
WSPListen(
- IN SOCKET s,
- IN INT backlog,
- OUT LPINT lpErrno)
-/*
- * FUNCTION: Listens for incoming connections
- * ARGUMENTS:
- * s = Socket descriptor
- * backlog = Maximum number of pending connection requests
- * lpErrno = Address of buffer for error information
- * RETURNS:
- * 0, or SOCKET_ERROR if the socket could not be bound
- */
+ SOCKET Handle,
+ int Backlog,
+ LPINT lpErrno)
{
- //PAFD_LISTEN_REQUEST MsafdRequest;
- FILE_REQUEST_LISTEN Request;
- FILE_REPLY_LISTEN Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
+ IO_STATUS_BLOCK IOSB;
+ AFD_LISTEN_DATA ListenData;
+ PSOCKET_INFORMATION Socket = NULL;
+ NTSTATUS Status;
+
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+
+ /* Set Up Listen Structure */
+ ListenData.UseSAN = FALSE;
+ ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance;
+ ListenData.Backlog = Backlog;
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
+ SockEvent,
+ NULL,
+ NULL,
+ &IOSB,
+ IOCTL_AFD_START_LISTEN,
+ &ListenData,
+ sizeof(ListenData),
+ NULL,
+ 0);
- AFD_DbgPrint(MAX_TRACE, ("s (0x%X) backlog (%d).\n", s, backlog));
+ /* Set to Listening */
+ Socket->SharedData.Listening = TRUE;
-/* MsafdRequest = (PMSAFD_LISTEN_REQUEST)HeapAlloc(
- GlobalHeap, 0, sizeof(MSAFD_LISTEN_REQUEST));
- if (MsafdRequest == NULL)
- {
- AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }*/
-
- Request.Backlog = backlog;
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_LISTEN,
- &Request,
- sizeof(FILE_REQUEST_LISTEN),
- &Reply,
- sizeof(FILE_REPLY_LISTEN));
- if (Status == STATUS_PENDING)
- {
- //AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- //InsertTailList(&MsAfdListenRequests, &MsafdRequest->ListEntry);
- }
- else if (!NT_SUCCESS(Status))
- {
- //HeapFree(GlobalHeap, 0, MsafdRequest);
- *lpErrno = Reply.Status;
- return SOCKET_ERROR;
- }
-
- return 0;
+ return 0;
}
-INT
-WSPAPI
+int
+WSPAPI
WSPSelect(
- IN INT nfds,
- IN OUT LPFD_SET readfds,
- IN OUT LPFD_SET writefds,
- IN OUT LPFD_SET exceptfds,
- IN CONST LPTIMEVAL timeout,
- OUT LPINT lpErrno)
-/*
- * FUNCTION: Returns status of one or more sockets
- * ARGUMENTS:
- * nfds = Always ignored
- * readfds = Pointer to socket set to be checked for readability (optional)
- * writefds = Pointer to socket set to be checked for writability (optional)
- * exceptfds = Pointer to socket set to be checked for errors (optional)
- * timeout = Pointer to a TIMEVAL structure indicating maximum wait time
- * (NULL means wait forever)
- * lpErrno = Address of buffer for error information
- * RETURNS:
- * Number of ready socket descriptors, or SOCKET_ERROR if an error ocurred
- */
+ int nfds,
+ fd_set *readfds,
+ fd_set *writefds,
+ fd_set *exceptfds,
+ struct timeval *timeout,
+ LPINT lpErrno)
{
- PFILE_REQUEST_SELECT Request;
- FILE_REPLY_SELECT Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- DWORD Size;
- DWORD ReadSize;
- DWORD WriteSize;
- DWORD ExceptSize;
- PVOID Current;
-
- AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n",
- readfds, writefds, exceptfds));
-#if 0
- /* FIXME: For now, all reads are timed out immediately */
- if (readfds != NULL) {
- AFD_DbgPrint(MID_TRACE, ("Timing out read query.\n"));
- *lpErrno = WSAETIMEDOUT;
- return SOCKET_ERROR;
- }
-
- /* FIXME: For now, always allow write */
- if (writefds != NULL) {
- AFD_DbgPrint(MID_TRACE, ("Setting one socket writeable.\n"));
- *lpErrno = NO_ERROR;
- return 1;
- }
-#endif
-
- ReadSize = 0;
- if ((readfds != NULL) && (readfds->fd_count > 0)) {
- ReadSize = (readfds->fd_count * sizeof(SOCKET)) + sizeof(UINT);
- }
-
- WriteSize = 0;
- if ((writefds != NULL) && (writefds->fd_count > 0)) {
- WriteSize = (writefds->fd_count * sizeof(SOCKET)) + sizeof(UINT);
- }
-
- ExceptSize = 0;
- if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) {
- ExceptSize = (exceptfds->fd_count * sizeof(SOCKET)) + sizeof(UINT);
- }
-
- Size = ReadSize + WriteSize + ExceptSize;
-
- Request = (PFILE_REQUEST_SELECT)HeapAlloc(
- GlobalHeap, 0, sizeof(FILE_REQUEST_SELECT) + Size);
- if (!Request) {
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- /* Put FD SETs after request structure */
- Current = (Request + 1);
-
- if (ReadSize > 0) {
- Request->ReadFDSet = (LPFD_SET)Current;
- Current += ReadSize;
- RtlCopyMemory(Request->ReadFDSet, readfds, ReadSize);
- } else {
- Request->ReadFDSet = NULL;
- }
-
- if (WriteSize > 0) {
- Request->WriteFDSet = (LPFD_SET)Current;
- Current += WriteSize;
- RtlCopyMemory(Request->WriteFDSet, writefds, WriteSize);
- } else {
- Request->WriteFDSet = NULL;
- }
-
- if (ExceptSize > 0) {
- Request->ExceptFDSet = (LPFD_SET)Current;
- RtlCopyMemory(Request->ExceptFDSet, exceptfds, ExceptSize);
- } else {
- Request->ExceptFDSet = NULL;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("R1 (0x%X) W1 (0x%X).\n", Request->ReadFDSet, Request->WriteFDSet));
-
- Status = NtDeviceIoControlFile(
- CommandChannel,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_SELECT,
- Request,
- sizeof(FILE_REQUEST_SELECT) + Size,
- &Reply,
- sizeof(FILE_REPLY_SELECT));
+ IO_STATUS_BLOCK IOSB;
+ PAFD_POLL_INFO PollInfo;
+ NTSTATUS Status;
+ ULONG HandleCount;
+ ULONG PollBufferSize;
+ LARGE_INTEGER uSec;
+ PVOID PollBuffer;
+ ULONG i, j = 0;
+
+ /* Find out how many sockets we have, and how large the buffer needs to be */
+ HandleCount = ( readfds ? readfds->fd_count : 0 ) +
+ ( writefds ? writefds->fd_count : 0 ) +
+ ( exceptfds ? exceptfds->fd_count : 0 );
+ PollBufferSize = sizeof(*PollInfo) + (HandleCount * sizeof(AFD_HANDLE));
+
+ /* Allocate */
+ PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
+ PollInfo = (PAFD_POLL_INFO)PollBuffer;
+
+ /* Convert Timeout to NT Format */
+ if (timeout == NULL) {
+ PollInfo->Timeout.u.LowPart = -1;
+ PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
+ } else {
+ PollInfo->Timeout = RtlEnlargedIntegerMultiply(timeout->tv_sec, -10000000);
+ uSec = RtlEnlargedIntegerMultiply(timeout->tv_usec, -10);
+ PollInfo->Timeout.QuadPart += uSec.QuadPart;
+ }
+
+ /* Number of handles for AFD to Check */
+ PollInfo->HandleCount = HandleCount;
+ PollInfo->Unknown = 0;
+
+ if (readfds != NULL) {
+ for (i = 0; i < readfds->fd_count; i++, j++) {
+ PollInfo->Handles[j].Handle = readfds->fd_array[i];
+ PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
+ }
+ } else if (writefds != NULL) {
+ for (i = 0; i < writefds->fd_count; i++, j++) {
+ PollInfo->Handles[j].Handle = writefds->fd_array[i];
+ PollInfo->Handles[j].Events = AFD_EVENT_SEND;
+ }
+
+ } else if (exceptfds != NULL) {
+ for (i = 0; i < exceptfds->fd_count; i++, j++) {
+ PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
+ PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
+ }
+ }
- HeapFree(GlobalHeap, 0, Request);
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle,
+ SockEvent,
+ NULL,
+ NULL,
+ &IOSB,
+ IOCTL_AFD_SELECT,
+ PollInfo,
+ PollBufferSize,
+ PollInfo,
+ PollBufferSize);
+ /* Wait for Completition */
if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject(CommandChannel, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
+ WaitForSingleObject(SockEvent, 0);
}
- AFD_DbgPrint(MAX_TRACE, ("Select successful. Status (0x%X) Count (0x%X).\n",
- Reply.Status, Reply.SocketCount));
-
- *lpErrno = Reply.Status;
+ /* Clear the Structures */
+ readfds ? FD_ZERO(readfds) : 0;
+ writefds ? FD_ZERO(writefds) : 0;
+ exceptfds ? FD_ZERO(exceptfds) : 0;
+
+ /* Loop through return structure */
+ HandleCount = PollInfo->HandleCount;
+
+ /* Return in FDSET Format */
+ for (i = 0; i < HandleCount; i++) {
+ switch (PollInfo->Handles[i].Events) {
+
+ case AFD_EVENT_RECEIVE:
+ case AFD_EVENT_DISCONNECT:
+ case AFD_EVENT_ABORT:
+ case AFD_EVENT_ACCEPT:
+ case AFD_EVENT_CLOSE:
+ FD_SET(PollInfo->Handles[i].Handle, readfds);
+ break;
+
+ case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
+ FD_SET(PollInfo->Handles[i].Handle, writefds);
+ break;
+
+ case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
+ FD_SET(PollInfo->Handles[i].Handle, exceptfds);
+ break;
+ }
+ }
- return Reply.SocketCount;
+ return 0;
}
SOCKET
-WSPAPI
+WSPAPI
WSPAccept(
- IN SOCKET s,
- OUT LPSOCKADDR addr,
- IN OUT LPINT addrlen,
- IN LPCONDITIONPROC lpfnCondition,
- IN DWORD dwCallbackData,
- OUT LPINT lpErrno)
-{
- FILE_REQUEST_ACCEPT Request;
- FILE_REPLY_ACCEPT Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
+ SOCKET Handle,
+ struct sockaddr *SocketAddress,
+ int *SocketAddressLength,
+ LPCONDITIONPROC lpfnCondition,
+ DWORD_PTR dwCallbackData,
+ LPINT lpErrno)
+{
+ IO_STATUS_BLOCK IOSB;
+ PAFD_RECEIVED_ACCEPT_DATA ListenReceiveData;
+ AFD_ACCEPT_DATA AcceptData;
+ AFD_DEFER_ACCEPT_DATA DeferData;
+ AFD_PENDING_ACCEPT_DATA PendingAcceptData;
+ PSOCKET_INFORMATION Socket = NULL;
+ NTSTATUS Status;
+ struct fd_set ReadSet;
+ struct timeval Timeout;
+ PVOID PendingData;
+ ULONG PendingDataLength;
+ PVOID CalleeDataBuffer;
+ WSABUF CallerData, CalleeID, CallerID, CalleeData;
+ PSOCKADDR RemoteAddress = NULL;
+ GROUP GroupID = 0;
+ ULONG CallBack;
+ WSAPROTOCOL_INFOW ProtocolInfo;
+ SOCKET AcceptSocket;
+ UCHAR ReceiveBuffer[0x1A];
+
+ /* Dynamic Structure...ugh */
+ ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer;
+
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+
+ /* If this is non-blocking, make sure there's something for us to accept */
+ FD_ZERO(&ReadSet);
+ FD_SET(Socket->Handle, &ReadSet);
+ Timeout.tv_sec=0;
+ Timeout.tv_usec=0;
+ WSPSelect(0, &ReadSet, NULL, NULL, &Timeout, NULL);
+ if (ReadSet.fd_array[0] != Socket->Handle) return 0;
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
+ SockEvent,
+ NULL,
+ NULL,
+ &IOSB,
+ IOCTL_AFD_WAIT_FOR_LISTEN,
+ NULL,
+ 0,
+ ListenReceiveData,
+ 0xA + sizeof(*ListenReceiveData));
+
+ if (lpfnCondition != NULL) {
+ if ((Socket->SharedData.ServiceFlags1 & XP1_CONNECT_DATA) != 0) {
+
+ /* Find out how much data is pending */
+ PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber;
+ PendingAcceptData.ReturnSize = TRUE;
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
+ SockEvent,
+ NULL,
+ NULL,
[truncated at 1000 lines; 851 more skipped]
reactos/lib/msafd/misc
diff -u -r1.1 -r1.2
--- event.c 4 Jul 2001 20:40:19 -0000 1.1
+++ event.c 18 Jul 2004 22:49:17 -0000 1.2
@@ -4,58 +4,103 @@
* FILE: misc/event.c
* PURPOSE: Event handling
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Alex Ionescu (alex@relsoft.net)
* REVISIONS:
* CSH 15/06-2001 Created
+ * Alex 16/07/2004 - Complete Rewrite
*/
+
#include <msafd.h>
-INT
-WSPAPI
+int
+WSPAPI
WSPEventSelect(
- IN SOCKET s,
- IN WSAEVENT hEventObject,
- IN LONG lNetworkEvents,
- OUT LPINT lpErrno)
+ SOCKET Handle,
+ WSAEVENT hEventObject,
+ long lNetworkEvents,
+ LPINT lpErrno)
{
- FILE_REQUEST_EVENTSELECT Request;
- FILE_REPLY_EVENTSELECT Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
-
- Request.hEventObject = hEventObject;
- Request.lNetworkEvents = lNetworkEvents;
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_EVENTSELECT,
- &Request,
- sizeof(FILE_REQUEST_EVENTSELECT),
- &Reply,
- sizeof(FILE_REPLY_EVENTSELECT));
- if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
+ IO_STATUS_BLOCK IOSB;
+ AFD_EVENT_SELECT_INFO EventSelectInfo;
+ PSOCKET_INFORMATION Socket = NULL;
+ NTSTATUS Status;
+ ULONG BlockMode;
+
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+
+ /* Set Socket to Non-Blocking */
+ BlockMode = 1;
+ SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL);
+ Socket->SharedData.NonBlocking = TRUE;
+
+ /* Deactivate Async Select if there is one */
+ if (Socket->EventObject) {
+ //SockAsyncSelect(Socket, NULL, 0, 0);
}
- AFD_DbgPrint(MAX_TRACE, ("Event select successful. Status (0x%X).\n",
- Reply.Status));
+ /* Set Structure Info */
+ EventSelectInfo.EventObject = hEventObject;
+ EventSelectInfo.Events = 0;
+
+ /* Set Events to wait for */
+ if (lNetworkEvents & FD_READ) {
+ EventSelectInfo.Events |= AFD_EVENT_RECEIVE;
+ }
+
+ if (lNetworkEvents & FD_WRITE) {
+ EventSelectInfo.Events |= AFD_EVENT_SEND;
+ }
+
+ if (lNetworkEvents & FD_OOB) {
+ EventSelectInfo.Events |= AFD_EVENT_OOB_RECEIVE;
+ }
+
+ if (lNetworkEvents & FD_ACCEPT) {
+ EventSelectInfo.Events |= AFD_EVENT_ACCEPT;
+ }
+
+ if (lNetworkEvents & FD_CONNECT) {
+ EventSelectInfo.Events |= AFD_EVENT_CONNECT | AFD_EVENT_CONNECT_FAIL;
+ }
+
+ if (lNetworkEvents & FD_CLOSE) {
+ EventSelectInfo.Events |= AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
+ }
+
+ if (lNetworkEvents & FD_QOS) {
+ EventSelectInfo.Events |= AFD_EVENT_QOS;
+ }
+
+ if (lNetworkEvents & FD_GROUP_QOS) {
+ EventSelectInfo.Events |= AFD_EVENT_GROUP_QOS;
+ }
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile((HANDLE)Handle,
+ SockEvent,
+ NULL,
+ NULL,
+ &IOSB,
+ IOCTL_AFD_EVENT_SELECT,
+ &EventSelectInfo,
+ sizeof(EventSelectInfo),
+ NULL,
+ 0);
+
+ /* Wait for return */
+ if (Status == STATUS_PENDING) {
+ WaitForSingleObject(SockEvent, 0);
+ }
- *lpErrno = Reply.Status;
+ /* Set Socket Data*/
+ Socket->EventObject = hEventObject;
+ Socket->NetworkEvents = lNetworkEvents;
- return 0;
+ return 0;
}
+
INT
WSPAPI
WSPEnumNetworkEvents(
@@ -64,42 +109,7 @@
OUT LPWSANETWORKEVENTS lpNetworkEvents,
OUT LPINT lpErrno)
{
- FILE_REQUEST_ENUMNETWORKEVENTS Request;
- FILE_REPLY_ENUMNETWORKEVENTS Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
-
- Request.hEventObject = hEventObject;
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_ENUMNETWORKEVENTS,
- &Request,
- sizeof(FILE_REQUEST_ENUMNETWORKEVENTS),
- &Reply,
- sizeof(FILE_REPLY_ENUMNETWORKEVENTS));
- if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("EnumNetworkEvents successful. Status (0x%X).\n",
- Reply.Status));
-
- *lpErrno = Reply.Status;
-
- return 0;
+ return 0;
}
/* EOF */
reactos/lib/msafd/misc
diff -u -r1.9 -r1.10
--- helpers.c 10 May 2004 11:56:07 -0000 1.9
+++ helpers.c 18 Jul 2004 22:49:17 -0000 1.10
@@ -4,8 +4,10 @@
* FILE: misc/helpers.c
* PURPOSE: Helper DLL management
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Alex Ionescu (alex@relsoft.net)
* REVISIONS:
* CSH 01/09-2000 Created
+ * Alex 16/07/2004 - Complete Rewrite
*/
#include <msafd.h>
#include <helpers.h>
@@ -13,275 +15,503 @@
CRITICAL_SECTION HelperDLLDatabaseLock;
LIST_ENTRY HelperDLLDatabaseListHead;
-PWSHELPER_DLL CreateHelperDLL(
- LPWSTR LibraryName)
-{
- PWSHELPER_DLL HelperDLL;
-
- HelperDLL = HeapAlloc(GlobalHeap, 0, sizeof(WSHELPER_DLL));
- if (!HelperDLL)
- return NULL;
-
- InitializeCriticalSection(&HelperDLL->Lock);
- HelperDLL->hModule = NULL;
- lstrcpyW(HelperDLL->LibraryName, LibraryName);
- HelperDLL->Mapping = NULL;
-
- EnterCriticalSection(&HelperDLLDatabaseLock);
- InsertTailList(&HelperDLLDatabaseListHead, &HelperDLL->ListEntry);
- LeaveCriticalSection(&HelperDLLDatabaseLock);
-
- AFD_DbgPrint(MAX_TRACE, ("Returning helper at (0x%X).\n", HelperDLL));
- return HelperDLL;
-}
-
-
-INT DestroyHelperDLL(
- PWSHELPER_DLL HelperDLL)
+INT
+SockGetTdiName(
+ PINT AddressFamily,
+ PINT SocketType,
+ PINT Protocol,
+ GROUP Group,
+ DWORD Flags,
+ PUNICODE_STRING TransportName,
+ PVOID *HelperDllContext,
+ PHELPER_DATA *HelperDllData,
+ PDWORD Events)
{
- INT Status;
-
- AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X).\n", HelperDLL));
-
- EnterCriticalSection(&HelperDLLDatabaseLock);
- RemoveEntryList(&HelperDLL->ListEntry);
- LeaveCriticalSection(&HelperDLLDatabaseLock);
+ PHELPER_DATA HelperData;
+ PWSTR Transports;
+ PWSTR Transport;
+ PWINSOCK_MAPPING Mapping;
+ PLIST_ENTRY Helpers;
+ INT Status;
+
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ /* Check in our Current Loaded Helpers */
+ for (Helpers = SockHelpersListHead.Flink;
+ Helpers != &SockHelpersListHead;
+ Helpers = Helpers->Flink ) {
+
+ HelperData = CONTAINING_RECORD(Helpers, HELPER_DATA, Helpers);
+
+ /* See if this Mapping works for us */
+ if (SockIsTripleInMapping (HelperData->Mapping,
+ *AddressFamily,
+ *SocketType,
+ *Protocol)) {
+
+ /* Call the Helper Dll function get the Transport Name */
+ if (HelperData->WSHOpenSocket2 == NULL ) {
+
+ /* DLL Doesn't support WSHOpenSocket2, call the old one */
+ HelperData->WSHOpenSocket(AddressFamily,
+ SocketType,
+ Protocol,
+ TransportName,
+ HelperDllContext,
+ Events
+ );
+ } else {
+ HelperData->WSHOpenSocket2(AddressFamily,
+ SocketType,
+ Protocol,
+ Group,
+ Flags,
+ TransportName,
+ HelperDllContext,
+ Events
+ );
+ }
- if (HelperDLL->hModule) {
- Status = UnloadHelperDLL(HelperDLL);
- } else {
- Status = NO_ERROR;
+ /* Return the Helper Pointers */
+ *HelperDllData = HelperData;
+ return NO_ERROR;
+ }
}
- if (HelperDLL->Mapping)
- HeapFree(GlobalHeap, 0, HelperDLL->Mapping);
+ /* Get the Transports available */
+ Status = SockLoadTransportList(&Transports);
- DeleteCriticalSection(&HelperDLL->Lock);
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Can't get transport list\n"));
+ return Status;
+ }
+
+ /* Loop through each transport until we find one that can satisfy us */
+ for (Transport = Transports;
+ *Transports != 0;
+ Transport += wcslen(Transport) + 1) {
+
+ /* See what mapping this Transport supports */
+ Status = SockLoadTransportMapping(Transport, &Mapping);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Can't get mapping\n"));
+ HeapFree(GlobalHeap, 0, Transports);
+ return Status;
+ }
- HeapFree(GlobalHeap, 0, HelperDLL);
+ /* See if this Mapping works for us */
+ if (SockIsTripleInMapping(Mapping, *AddressFamily, *SocketType, *Protocol)) {
- return Status;
-}
+ /* It does, so load the DLL associated with it */
+ Status = SockLoadHelperDll(Transport, Mapping, &HelperData);
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Can't load helper DLL\n"));
+ HeapFree(GlobalHeap, 0, Transports);
+ HeapFree(GlobalHeap, 0, Mapping);
+ return Status;
+ }
-PWSHELPER_DLL LocateHelperDLL(
- LPWSAPROTOCOL_INFOW lpProtocolInfo)
-{
- PLIST_ENTRY CurrentEntry;
- PWSHELPER_DLL HelperDLL;
- UINT i;
-
- EnterCriticalSection(&HelperDLLDatabaseLock);
- CurrentEntry = HelperDLLDatabaseListHead.Flink;
- while (CurrentEntry != &HelperDLLDatabaseListHead) {
- HelperDLL = CONTAINING_RECORD(CurrentEntry,
- WSHELPER_DLL,
- ListEntry);
-
- for (i = 0; i < HelperDLL->Mapping->Rows; i++) {
- if ((lpProtocolInfo->iAddressFamily == (INT) HelperDLL->Mapping->Mapping[i].AddressFamily) &&
- (lpProtocolInfo->iSocketType == (INT) HelperDLL->Mapping->Mapping[i].SocketType) &&
- ((lpProtocolInfo->iProtocol == (INT) HelperDLL->Mapping->Mapping[i].Protocol) ||
- (lpProtocolInfo->iSocketType == SOCK_RAW))) {
- LeaveCriticalSection(&HelperDLLDatabaseLock);
- AFD_DbgPrint(MAX_TRACE, ("Returning helper DLL at (0x%X).\n", HelperDLL));
- return HelperDLL;
+ /* Call the Helper Dll function get the Transport Name */
+ if (HelperData->WSHOpenSocket2 == NULL) {
+ /* DLL Doesn't support WSHOpenSocket2, call the old one */
+ HelperData->WSHOpenSocket(AddressFamily,
+ SocketType,
+ Protocol,
+ TransportName,
+ HelperDllContext,
+ Events
+ );
+ } else {
+ HelperData->WSHOpenSocket2(AddressFamily,
+ SocketType,
+ Protocol,
+ Group,
+ Flags,
+ TransportName,
+ HelperDllContext,
+ Events
+ );
}
- }
- CurrentEntry = CurrentEntry->Flink;
+ /* Return the Helper Pointers */
+ *HelperDllData = HelperData;
+ HeapFree(GlobalHeap, 0, Transports);
+ HeapFree(GlobalHeap, 0, Mapping);
+ return NO_ERROR;
+ }
+
+ HeapFree(GlobalHeap, 0, Mapping);
}
- LeaveCriticalSection(&HelperDLLDatabaseLock);
-
- AFD_DbgPrint(MAX_TRACE, ("Could not locate helper DLL.\n"));
-
- return NULL;
+ HeapFree(GlobalHeap, 0, Transports);
+ return WSAEINVAL;
}
-
-INT GetHelperDLLEntries(
- PWSHELPER_DLL HelperDLL)
+INT
+SockLoadTransportMapping(
+ PWSTR TransportName,
+ PWINSOCK_MAPPING *Mapping)
{
- PVOID e;
-
- /* The following functions MUST be supported */
- e = GetProcAddress(HelperDLL->hModule, "WSHEnumProtocols");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHEnumProtocols = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHGetSockaddrType");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHGetSockaddrType = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHGetSocketInformation");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHGetSocketInformation = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHGetWildcardSockaddr");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHGetWildcardSockaddr = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHGetWinsockMapping");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHGetWinsockMapping = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHNotify");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHNotify = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHOpenSocket");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHOpenSocket = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHSetSocketInformation");
- if (!e) return ERROR_BAD_PROVIDER;
- HelperDLL->EntryTable.lpWSHSetSocketInformation = e;
-
-
- /*
- The following functions are OPTIONAL.
- Whoever wants to call them, must check that the pointer is not NULL.
- */
- e = GetProcAddress(HelperDLL->hModule, "WSHAddressToString");
- HelperDLL->EntryTable.lpWSHAddressToString = e;
-
- e = GetProcAddress(HelperDLL->hModule, "WSHGetBroadcastSockaddr");
- HelperDLL->EntryTable.lpWSHGetBroadcastSockaddr = e;
+ PWSTR TransportKey;
+ HKEY KeyHandle;
+ ULONG MappingSize;
+ LONG Status;
+
+ AFD_DbgPrint(MID_TRACE,("Called: TransportName %ws\n", TransportName));
+
+ /* Allocate a Buffer */
+ TransportKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));
+
+ /* Check for error */
+ if (TransportKey == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ return WSAEINVAL;
+ }
- e = GetProcAddress(HelperDLL->hModule, "WSHGetProviderGuid");
- HelperDLL->EntryTable.lpWSHGetProviderGuid = e;
+ /* Generate the right key name */
+ wcscpy(TransportKey, L"System\\CurrentControlSet\\Services\\");
+ wcscat(TransportKey, TransportName);
+ wcscat(TransportKey, L"\\Parameters\\Winsock");
+
+ /* Open the Key */
+ Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TransportKey, 0, KEY_READ, &KeyHandle);
+
+ /* We don't need the Transport Key anymore */
+ HeapFree(GlobalHeap, 0, TransportKey);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n"));
+ return WSAEINVAL;
+ }
- e = GetProcAddress(HelperDLL->hModule, "WSHGetWSAProtocolInfo");
- HelperDLL->EntryTable.lpWSHGetWSAProtocolInfo = e;
+ /* Find out how much space we need for the Mapping */
+ Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, NULL, &MappingSize);
- e = GetProcAddress(HelperDLL->hModule, "WSHIoctl");
- HelperDLL->EntryTable.lpWSHIoctl = e;
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n"));
+ return WSAEINVAL;
+ }
- e = GetProcAddress(HelperDLL->hModule, "WSHJoinLeaf");
- HelperDLL->EntryTable.lpWSHJoinLeaf = e;
+ /* Allocate Memory for the Mapping */
+ *Mapping = HeapAlloc(GlobalHeap, 0, MappingSize);
- e = GetProcAddress(HelperDLL->hModule, "WSHOpenSocket2");
- HelperDLL->EntryTable.lpWSHOpenSocket2 = e;
+ /* Check for error */
+ if (*Mapping == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ return WSAEINVAL;
+ }
- e = GetProcAddress(HelperDLL->hModule, "WSHStringToAddress");
- HelperDLL->EntryTable.lpWSHStringToAddress = e;
+ /* Read the Mapping */
+ Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, (LPBYTE)*Mapping, &MappingSize);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n"));
+ HeapFree(GlobalHeap, 0, *Mapping);
+ return WSAEINVAL;
+ }
- return NO_ERROR;
+ /* Close key and return */
+ RegCloseKey(KeyHandle);
+ return 0;
}
-
-INT LoadHelperDLL(
- PWSHELPER_DLL HelperDLL)
+INT
+SockLoadTransportList(
+ PWSTR *TransportList)
{
- INT Status = NO_ERROR;
-
- AFD_DbgPrint(MAX_TRACE, ("Loading helper dll at (0x%X).\n", HelperDLL));
-
- if (!HelperDLL->hModule) {
- /* DLL is not loaded so load it now */
- HelperDLL->hModule = LoadLibrary(HelperDLL->LibraryName);
-
- AFD_DbgPrint(MAX_TRACE, ("hModule is (0x%X).\n", HelperDLL->hModule));
-
- if (HelperDLL->hModule) {
- Status = GetHelperDLLEntries(HelperDLL);
- } else
- Status = ERROR_DLL_NOT_FOUND;
- } else
- Status = NO_ERROR;
-
- AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
-
- return Status;
-}
+ ULONG TransportListSize;
+ HKEY KeyHandle;
+ LONG Status;
+ AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+ /* Open the Transports Key */
+ Status = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters",
+ 0,
+ KEY_READ,
+ &KeyHandle);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n"));
+ return WSAEINVAL;
+ }
+
+ /* Get the Transport List Size */
+ Status = RegQueryValueExW(KeyHandle,
+ L"Transports",
+ NULL,
+ NULL,
+ NULL,
+ &TransportListSize);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n"));
+ return WSAEINVAL;
+ }
-INT UnloadHelperDLL(
- PWSHELPER_DLL HelperDLL)
-{
- INT Status = NO_ERROR;
+ /* Allocate Memory for the Transport List */
+ *TransportList = HeapAlloc(GlobalHeap, 0, TransportListSize);
- AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X) hModule (0x%X).\n", HelperDLL, HelperDLL->hModule));
+ /* Check for error */
+ if (*TransportList == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ return WSAEINVAL;
+ }
- if (HelperDLL->hModule) {
- if (!FreeLibrary(HelperDLL->hModule)) {
- Status = GetLastError();
- }
- HelperDLL->hModule = NULL;
+ /* Get the Transports */
+ Status = RegQueryValueExW (KeyHandle,
+ L"Transports",
+ NULL,
+ NULL,
+ (LPBYTE)*TransportList,
+ &TransportListSize);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading transport list registry\n"));
+ HeapFree(GlobalHeap, 0, *TransportList);
+ return WSAEINVAL;
}
- return Status;
+ /* Close key and return */
+ RegCloseKey(KeyHandle);
+ return 0;
}
-
-VOID CreateHelperDLLDatabase(VOID)
+INT
+SockLoadHelperDll(
+ PWSTR TransportName,
+ PWINSOCK_MAPPING Mapping,
+ PHELPER_DATA *HelperDllData)
{
- PWSHELPER_DLL HelperDLL;
-
- InitializeCriticalSection(&HelperDLLDatabaseLock);
-
- InitializeListHead(&HelperDLLDatabaseListHead);
-
- /* FIXME: Read helper DLL configuration from registry */
- HelperDLL = CreateHelperDLL(L"wshtcpip.dll");
- if (!HelperDLL)
- return;
-
- HelperDLL->Mapping = HeapAlloc(
- GlobalHeap,
- 0,
- 5 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
- if (!HelperDLL->Mapping)
- return;
+ PHELPER_DATA HelperData;
+ PWSTR HelperDllName;
+ PWSTR FullHelperDllName;
+ ULONG HelperDllNameSize;
+ PWSTR HelperKey;
+ HKEY KeyHandle;
+ ULONG DataSize;
+ LONG Status;
+
+ /* Allocate space for the Helper Structure and TransportName */
+ HelperData = HeapAlloc(GlobalHeap, 0, sizeof(*HelperData) + (wcslen(TransportName) + 1) * sizeof(WCHAR));
- HelperDLL->Mapping->Rows = 5;
- HelperDLL->Mapping->Columns = 3;
+ /* Check for error */
+ if (HelperData == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ return WSAEINVAL;
+ }
+
+ /* Allocate Space for the Helper DLL Key */
+ HelperKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR));
+
+ /* Check for error */
+ if (HelperKey == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ HeapFree(GlobalHeap, 0, HelperData);
+ return WSAEINVAL;
+ }
- HelperDLL->Mapping->Mapping[0].AddressFamily = AF_INET;
- HelperDLL->Mapping->Mapping[0].SocketType = SOCK_STREAM;
- HelperDLL->Mapping->Mapping[0].Protocol = 0;
+ /* Generate the right key name */
+ wcscpy(HelperKey, L"System\\CurrentControlSet\\Services\\");
+ wcscat(HelperKey, TransportName);
+ wcscat(HelperKey, L"\\Parameters\\Winsock");
+
+ /* Open the Key */
+ Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, HelperKey, 0, KEY_READ, &KeyHandle);
+
+ HeapFree(GlobalHeap, 0, HelperKey);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading helper DLL parameters\n"));
+ HeapFree(GlobalHeap, 0, HelperData);
+ return WSAEINVAL;
+ }
+
+ /* Read Size of SockAddr Structures */
+ DataSize = sizeof(HelperData->MinWSAddressLength);
+ HelperData->MinWSAddressLength = 16;
+ RegQueryValueExW (KeyHandle,
+ L"MinSockaddrLength",
+ NULL,
+ NULL,
+ (LPBYTE)&HelperData->MinWSAddressLength,
+ &DataSize);
+ DataSize = sizeof(HelperData->MinWSAddressLength);
+ HelperData->MaxWSAddressLength = 16;
+ RegQueryValueExW (KeyHandle,
+ L"MaxSockaddrLength",
+ NULL,
+ NULL,
+ (LPBYTE)&HelperData->MaxWSAddressLength,
+ &DataSize);
+
+ /* Size of TDI Structures */
+ HelperData->MinTDIAddressLength = HelperData->MinWSAddressLength + 6;
+ HelperData->MaxTDIAddressLength = HelperData->MaxWSAddressLength + 6;
+
+ /* Read Delayed Acceptance Setting */
+ DataSize = sizeof(DWORD);
+ HelperData->UseDelayedAcceptance = FALSE;
+ RegQueryValueExW (KeyHandle,
+ L"UseDelayedAcceptance",
+ NULL,
+ NULL,
+ (LPBYTE)&HelperData->UseDelayedAcceptance,
+ &DataSize);
+
+ /* Allocate Space for the Helper DLL Names */
+ HelperDllName = HeapAlloc(GlobalHeap, 0, 512);
+
+ /* Check for error */
+ if (HelperDllName == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ HeapFree(GlobalHeap, 0, HelperData);
+ return WSAEINVAL;
+ }
- HelperDLL->Mapping->Mapping[1].AddressFamily = AF_INET;
- HelperDLL->Mapping->Mapping[1].SocketType = SOCK_STREAM;
- HelperDLL->Mapping->Mapping[1].Protocol = IPPROTO_TCP;
+ FullHelperDllName = HeapAlloc(GlobalHeap, 0, 512);
+
+ /* Check for error */
+ if (FullHelperDllName == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n"));
+ HeapFree(GlobalHeap, 0, HelperDllName);
+ HeapFree(GlobalHeap, 0, HelperData);
+ return WSAEINVAL;
+ }
- HelperDLL->Mapping->Mapping[2].AddressFamily = AF_INET;
- HelperDLL->Mapping->Mapping[2].SocketType = SOCK_DGRAM;
- HelperDLL->Mapping->Mapping[2].Protocol = 0;
+ /* Get the name of the Helper DLL*/
+ DataSize = 512;
+ Status = RegQueryValueExW (KeyHandle,
+ L"HelperDllName",
+ NULL,
+ NULL,
+ (LPBYTE)HelperDllName,
+ &DataSize);
+
+ /* Check for error */
+ if (Status) {
+ AFD_DbgPrint(MIN_TRACE, ("Error reading helper DLL parameters\n"));
+ HeapFree(GlobalHeap, 0, FullHelperDllName);
+ HeapFree(GlobalHeap, 0, HelperDllName);
+ HeapFree(GlobalHeap, 0, HelperData);
+ return WSAEINVAL;
+ }
- HelperDLL->Mapping->Mapping[3].AddressFamily = AF_INET;
- HelperDLL->Mapping->Mapping[3].SocketType = SOCK_DGRAM;
- HelperDLL->Mapping->Mapping[3].Protocol = IPPROTO_UDP;
+ /* Get the Full name, expanding Environment Strings */
+ HelperDllNameSize = ExpandEnvironmentStringsW (HelperDllName,
+ FullHelperDllName,
+ 256);
+
+ /* Load the DLL */
+ HelperData->hInstance = LoadLibraryW(FullHelperDllName);
+
+ HeapFree(GlobalHeap, 0, HelperDllName);
+ HeapFree(GlobalHeap, 0, FullHelperDllName);
+
+ if (HelperData->hInstance == NULL) {
+ AFD_DbgPrint(MIN_TRACE, ("Error loading helper DLL\n"));
+ HeapFree(GlobalHeap, 0, HelperData);
+ return WSAEINVAL;
+ }
- HelperDLL->Mapping->Mapping[4].AddressFamily = AF_INET;
- HelperDLL->Mapping->Mapping[4].SocketType = SOCK_RAW;
- HelperDLL->Mapping->Mapping[4].Protocol = 0;
+ /* Close Key */
+ RegCloseKey(KeyHandle);
- LoadHelperDLL(HelperDLL);
+ /* Get the Pointers to the Helper Routines */
+ HelperData->WSHOpenSocket = (PWSH_OPEN_SOCKET)
+ GetProcAddress(HelperData->hInstance,
+ "WSHOpenSocket");
+ HelperData->WSHOpenSocket2 = (PWSH_OPEN_SOCKET2)
+ GetProcAddress(HelperData->hInstance,
+ "WSHOpenSocket2");
+ HelperData->WSHJoinLeaf = (PWSH_JOIN_LEAF)
+ GetProcAddress(HelperData->hInstance,
+ "WSHJoinLeaf");
+ HelperData->WSHNotify = (PWSH_NOTIFY)
+ GetProcAddress(HelperData->hInstance, "WSHNotify");
+ HelperData->WSHGetSocketInformation = (PWSH_GET_SOCKET_INFORMATION)
+ GetProcAddress(HelperData->hInstance,
+ "WSHGetSocketInformation");
+ HelperData->WSHSetSocketInformation = (PWSH_SET_SOCKET_INFORMATION)
+ GetProcAddress(HelperData->hInstance,
+ "WSHSetSocketInformation");
+ HelperData->WSHGetSockaddrType = (PWSH_GET_SOCKADDR_TYPE)
+ GetProcAddress(HelperData->hInstance,
+ "WSHGetSockaddrType");
+ HelperData->WSHGetWildcardSockaddr = (PWSH_GET_WILDCARD_SOCKEADDR)
+ GetProcAddress(HelperData->hInstance,
+ "WSHGetWildcardSockaddr");
+ HelperData->WSHGetBroadcastSockaddr = (PWSH_GET_BROADCAST_SOCKADDR)
+ GetProcAddress(HelperData->hInstance,
+ "WSHGetBroadcastSockaddr");
+ HelperData->WSHAddressToString = (PWSH_ADDRESS_TO_STRING)
+ GetProcAddress(HelperData->hInstance,
+ "WSHAddressToString");
+ HelperData->WSHStringToAddress = (PWSH_STRING_TO_ADDRESS)
+ GetProcAddress(HelperData->hInstance,
+ "WSHStringToAddress");
+ HelperData->WSHIoctl = (PWSH_IOCTL)
+ GetProcAddress(HelperData->hInstance,
+ "WSHIoctl");
+
+ /* Save the Mapping Structure and transport name */
+ HelperData->Mapping = Mapping;
+ wcscpy(HelperData->TransportName, TransportName);
+
+ /* Increment Reference Count */
+ HelperData->RefCount = 1;
+
+ /* Add it to our list */
+ InsertHeadList(&SockHelpersListHead, &HelperData->Helpers);
+
+ /* Return Pointers */
+ *HelperDllData = HelperData;
+ return 0;
}
-
-VOID DestroyHelperDLLDatabase(VOID)
+BOOL
+SockIsTripleInMapping(
+ PWINSOCK_MAPPING Mapping,
+ INT AddressFamily,
+ INT SocketType,
+ INT Protocol)
{
- PLIST_ENTRY CurrentEntry;
- PLIST_ENTRY NextEntry;
- PWSHELPER_DLL HelperDLL;
-
- CurrentEntry = HelperDLLDatabaseListHead.Flink;
- while (CurrentEntry != &HelperDLLDatabaseListHead) {
- NextEntry = CurrentEntry->Flink;
-
- HelperDLL = CONTAINING_RECORD(CurrentEntry,
- WSHELPER_DLL,
- ListEntry);
-
- DestroyHelperDLL(HelperDLL);
+ /* The Windows version returns more detailed information on which of the 3 parameters failed...we should do this later */
+ ULONG Row;
+
+ AFD_DbgPrint(MID_TRACE,("Called, Mapping rows = %d\n", Mapping->Rows));
- CurrentEntry = NextEntry;
+ /* Loop through Mapping to Find a matching one */
+ for (Row = 0; Row < Mapping->Rows; Row++) {
+ AFD_DbgPrint(MID_TRACE,("Examining: row %d: AF %d type %d proto %d\n",
+ Row,
+ (INT)Mapping->Mapping[Row].AddressFamily,
+ (INT)Mapping->Mapping[Row].SocketType,
+ (INT)Mapping->Mapping[Row].Protocol));
+
+ /* Check of all three values Match */
+ if (((INT)Mapping->Mapping[Row].AddressFamily == AddressFamily) &&
+ ((INT)Mapping->Mapping[Row].SocketType == SocketType) &&
+ ((INT)Mapping->Mapping[Row].Protocol == Protocol)) {
+ AFD_DbgPrint(MID_TRACE,("Found\n"));
+ return TRUE;
+ }
}
-
- DeleteCriticalSection(&HelperDLLDatabaseLock);
+ AFD_DbgPrint(MID_TRACE,("Not found\n"));
+ return FALSE;
}
/* EOF */
reactos/lib/msafd/misc
diff -u -r1.7 -r1.8
--- sndrcv.c 15 Jun 2004 02:56:13 -0000 1.7
+++ sndrcv.c 18 Jul 2004 22:49:17 -0000 1.8
@@ -4,8 +4,10 @@
* FILE: misc/sndrcv.c
* PURPOSE: Send/receive routines
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Alex Ionescu (alex@relsoft.net)
* REVISIONS:
* CSH 01/09-2000 Created
+ * Alex 16/07/2004 - Complete Rewrite
*/
#include <string.h>
#include <msafd.h>
@@ -25,253 +27,494 @@
}
-INT
+int
WSPAPI
WSPRecv(
- IN SOCKET s,
- IN OUT LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesRecvd,
- IN OUT LPDWORD lpFlags,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
- IN LPWSATHREADID lpThreadId,
- OUT LPINT lpErrno)
+ SOCKET Handle,
+ LPWSABUF lpBuffers,
+ DWORD dwBufferCount,
+ LPDWORD lpNumberOfBytesRead,
+ LPDWORD ReceiveFlags,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
+ LPWSATHREADID lpThreadId,
+ LPINT lpErrno)
{
- PFILE_REQUEST_RECVFROM Request;
- FILE_REPLY_RECVFROM Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- DWORD Size;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- Size = dwBufferCount * sizeof(WSABUF);
-
- Request = (PFILE_REQUEST_RECVFROM)HeapAlloc(
- GlobalHeap, 0, sizeof(FILE_REQUEST_RECVFROM) + Size);
- if (!Request) {
- AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- /* Put buffer pointers after request structure */
- Request->Buffers = (LPWSABUF)(Request + 1);
- Request->BufferCount = dwBufferCount;
- Request->Flags = lpFlags;
-
- RtlCopyMemory(Request->Buffers, lpBuffers, Size);
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_RECV,
- Request,
- sizeof(FILE_REQUEST_RECVFROM) + Size,
- &Reply,
- sizeof(FILE_REPLY_RECVFROM));
+ PIO_STATUS_BLOCK IOSB;
+ IO_STATUS_BLOCK DummyIOSB;
+ AFD_RECV_INFO RecvInfo;
+ NTSTATUS Status;
+ PVOID APCContext;
+ PVOID APCFunction;
+ HANDLE Event;
+
+ /* Set up the Receive Structure */
+ RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
+ RecvInfo.BufferCount = dwBufferCount;
+ RecvInfo.TdiFlags = 0;
+ RecvInfo.AfdFlags = 0;
+
+ /* Set the TDI Flags */
+ if (*ReceiveFlags == 0) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
+
+ } else {
+
+ if (*ReceiveFlags & MSG_OOB) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED;
+ } else {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
+ }
+
+ if (*ReceiveFlags & MSG_PEEK) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK;
+ }
+
+ if (*ReceiveFlags & MSG_PARTIAL) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
+ }
+ }
- HeapFree(GlobalHeap, 0, Request);
+ /* Verifiy if we should use APC */
- if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
+ if (lpOverlapped == NULL) {
- AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
- Reply.NumberOfBytesRecvd));
+ /* Not using Overlapped structure, so use normal blocking on event */
+ APCContext = NULL;
+ APCFunction = NULL;
+ Event = SockEvent;
+ IOSB = &DummyIOSB;
+
+ } else {
+
+ if (lpCompletionRoutine == NULL) {
+
+ /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+ APCContext = lpOverlapped;
+ APCFunction = NULL;
+ Event = lpOverlapped->hEvent;
+
+ } else {
+
+ /* Using Overlapped Structure and a Completition Routine, so use an APC */
+ APCFunction = NULL; // should be a private io completition function inside us
+ APCContext = lpCompletionRoutine;
+ RecvInfo.AfdFlags = AFD_SKIP_FIO;
+ }
- *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
- //*lpFlags = 0;
+ IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
+ RecvInfo.AfdFlags |= AFD_OVERLAPPED;
+ }
- return 0;
-}
+ IOSB->Status = STATUS_PENDING;
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile((HANDLE)Handle,
+ SockEvent,
+ APCFunction,
+ APCContext,
+ IOSB,
+ IOCTL_AFD_RECV,
+ &RecvInfo,
+ sizeof(RecvInfo),
+ NULL,
+ 0);
+
+ /* Wait for completition of not overlapped */
+ if (Status == STATUS_PENDING && lpOverlapped == NULL) {
+ WaitForSingleObject(SockEvent, 0); // BUGBUG, shouldn wait infintely for receive...
+ Status = IOSB->Status;
+ }
-INT
-WSPAPI
-WSPRecvDisconnect(
- IN SOCKET s,
- OUT LPWSABUF lpInboundDisconnectData,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
+ /* Return the Flags */
+ *ReceiveFlags = 0;
+ switch (Status) {
+
+ 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 0;
+ /* Return Number of bytes Read */
+ *lpNumberOfBytesRead = (DWORD)IOSB->Information;
+
+ /* Success */
+ return STATUS_SUCCESS;
}
-INT
-WSPAPI
+int
+WSPAPI
WSPRecvFrom(
- IN SOCKET s,
- IN OUT LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesRecvd,
- IN OUT LPDWORD lpFlags,
- OUT LPSOCKADDR lpFrom,
- IN OUT LPINT lpFromLen,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
- IN LPWSATHREADID lpThreadId,
- OUT LPINT lpErrno)
+ SOCKET Handle,
+ LPWSABUF lpBuffers,
+ DWORD dwBufferCount,
+ LPDWORD lpNumberOfBytesRead,
+ LPDWORD ReceiveFlags,
+ struct sockaddr *SocketAddress,
+ int *SocketAddressLength,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
+ LPWSATHREADID lpThreadId,
+ LPINT lpErrno)
{
- PFILE_REQUEST_RECVFROM Request;
- FILE_REPLY_RECVFROM Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- DWORD Size;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- Size = dwBufferCount * sizeof(WSABUF);
-
- Request = (PFILE_REQUEST_RECVFROM)HeapAlloc(
- GlobalHeap, 0, sizeof(FILE_REQUEST_RECVFROM) + Size);
- if (!Request) {
- AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- /* Put buffer pointers after request structure */
- Request->Buffers = (LPWSABUF)(Request + 1);
- Request->BufferCount = dwBufferCount;
- Request->Flags = lpFlags;
- Request->From = lpFrom;
- Request->FromLen = lpFromLen;
-
- RtlCopyMemory(Request->Buffers, lpBuffers, Size);
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_RECVFROM,
- Request,
- sizeof(FILE_REQUEST_RECVFROM) + Size,
- &Reply,
- sizeof(FILE_REPLY_RECVFROM));
+ PIO_STATUS_BLOCK IOSB;
+ IO_STATUS_BLOCK DummyIOSB;
+ AFD_RECV_INFO_UDP RecvInfo;
+ NTSTATUS Status;
+ PVOID APCContext;
+ PVOID APCFunction;
+ HANDLE Event;
+
+ /* Set up the Receive Structure */
+ RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
+ RecvInfo.BufferCount = dwBufferCount;
+ RecvInfo.TdiFlags = 0;
+ RecvInfo.AfdFlags = 0;
+ RecvInfo.AddressLength = SocketAddressLength;
+ RecvInfo.Address = SocketAddress;
+
+ /* Set the TDI Flags */
+ if (*ReceiveFlags == 0) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
+
+ } else {
+
+ if (*ReceiveFlags & MSG_OOB) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_EXPEDITED;
+ } else {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
+ }
+
+ if (*ReceiveFlags & MSG_PEEK) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK;
+ }
+
+ if (*ReceiveFlags & MSG_PARTIAL) {
+ RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL;
+ }
+ }
- HeapFree(GlobalHeap, 0, Request);
+ /* Verifiy if we should use APC */
- if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
- Reply.NumberOfBytesRecvd));
-
- *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
- //*lpFlags = 0;
- ((PSOCKADDR_IN)lpFrom)->sin_family = AF_INET;
- ((PSOCKADDR_IN)lpFrom)->sin_port = 0;
- ((PSOCKADDR_IN)lpFrom)->sin_addr.S_un.S_addr = 0x0100007F;
- *lpFromLen = sizeof(SOCKADDR_IN);
+ if (lpOverlapped == NULL) {
- return 0;
+ /* Not using Overlapped structure, so use normal blocking on event */
+ APCContext = NULL;
+ APCFunction = NULL;
+ Event = SockEvent;
+ IOSB = &DummyIOSB;
+
+ } else {
+
+ if (lpCompletionRoutine == NULL) {
+
+ /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+ APCContext = lpOverlapped;
+ APCFunction = NULL;
+ Event = lpOverlapped->hEvent;
+
+ } else {
+
+ /* Using Overlapped Structure and a Completition Routine, so use an APC */
+ APCFunction = NULL; // should be a private io completition function inside us
+ APCContext = lpCompletionRoutine;
+ RecvInfo.AfdFlags = AFD_SKIP_FIO;
+ }
+
+ IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
+ RecvInfo.AfdFlags |= AFD_OVERLAPPED;
+ }
+
+ IOSB->Status = STATUS_PENDING;
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile((HANDLE)Handle,
+ SockEvent,
+ APCFunction,
+ APCContext,
+ IOSB,
+ IOCTL_AFD_RECV_DATAGRAM,
+ &RecvInfo,
+ sizeof(RecvInfo),
+ NULL,
+ 0);
+
+ /* Wait for completition of not overlapped */
+ if (Status == STATUS_PENDING && lpOverlapped == NULL) {
+ WaitForSingleObject(SockEvent, 0); // BUGBUG, shouldn wait infintely for receive...
+ Status = IOSB->Status;
+ }
+
+ /* Return the Flags */
+ *ReceiveFlags = 0;
+ switch (Status) {
+
+ 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
-WSPAPI
+int
+WSPAPI
WSPSend(
- IN SOCKET s,
- IN LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesSent,
- IN DWORD dwFlags,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
- IN LPWSATHREADID lpThreadId,
- OUT LPINT lpErrno)
+ SOCKET Handle,
+ LPWSABUF lpBuffers,
+ DWORD dwBufferCount,
+ LPDWORD lpNumberOfBytesSent,
+ DWORD iFlags,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
+ LPWSATHREADID lpThreadId,
+ LPINT lpErrno)
{
- PFILE_REQUEST_SENDTO Request;
- FILE_REPLY_SENDTO Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- DWORD Size;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- Size = dwBufferCount * sizeof(WSABUF);
-CP
- Request = (PFILE_REQUEST_SENDTO)HeapAlloc(
- GlobalHeap, 0, sizeof(FILE_REQUEST_SENDTO) + Size);
- if (!Request) {
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-CP
-
- /* Put buffer pointers after request structure */
- Request->Buffers = (LPWSABUF)(Request + 1);
- Request->BufferCount = dwBufferCount;
- Request->Flags = dwFlags;
-CP
-
- RtlCopyMemory(Request->Buffers, lpBuffers, Size);
-CP
-
- Status = NtDeviceIoControlFile
- ( (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_SEND,
- Request,
- sizeof(FILE_REQUEST_SENDTO) + Size,
- &Reply,
- sizeof(FILE_REPLY_SENDTO));
-CP
+ PIO_STATUS_BLOCK IOSB;
+ IO_STATUS_BLOCK DummyIOSB;
+ AFD_SEND_INFO SendInfo;
+ NTSTATUS Status;
+ PVOID APCContext;
+ PVOID APCFunction;
+ HANDLE Event;
+
+ /* Set up the Send Structure */
+ SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
+ SendInfo.BufferCount = dwBufferCount;
+ SendInfo.TdiFlags = 0;
+ SendInfo.AfdFlags = 0;
+
+ /* Set the TDI Flags */
+ if (iFlags) {
+ if (iFlags & MSG_OOB) {
+ SendInfo.TdiFlags |= TDI_SEND_EXPEDITED;
+ }
+ if (iFlags & MSG_PARTIAL) {
+ SendInfo.TdiFlags |= TDI_SEND_PARTIAL;
+ }
+ }
+
+ /* Verifiy if we should use APC */
+ if (lpOverlapped == NULL) {
+
+ /* Not using Overlapped structure, so use normal blocking on event */
+ APCContext = NULL;
+ APCFunction = NULL;
+ Event = SockEvent;
+ IOSB = &DummyIOSB;
+
+ } else {
+
+ if (lpCompletionRoutine == NULL) {
+
+ /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+ APCContext = lpOverlapped;
+ APCFunction = NULL;
+ Event = lpOverlapped->hEvent;
+
+ } else {
+
+ /* Using Overlapped Structure and a Completition Routine, so use an APC */
+ APCFunction = NULL; // should be a private io completition function inside us
+ APCContext = lpCompletionRoutine;
+ SendInfo.AfdFlags = AFD_SKIP_FIO;
+ }
+
+ IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
+ SendInfo.AfdFlags |= AFD_OVERLAPPED;
+ }
+
+ IOSB->Status = STATUS_PENDING;
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile((HANDLE)Handle,
+ SockEvent,
+ APCFunction,
+ APCContext,
+ IOSB,
+ IOCTL_AFD_SEND,
+ &SendInfo,
+ sizeof(SendInfo),
+ NULL,
+ 0);
+
+ /* Wait for completition of not overlapped */
+ if (Status == STATUS_PENDING && lpOverlapped == NULL) {
+ WaitForSingleObject(SockEvent, 0); // BUGBUG, shouldn wait infintely for send...
+ Status = IOSB->Status;
+ }
- /* HeapFree(GlobalHeap, 0, Request); */
-CP
if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-CP
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
+ return WSA_IO_PENDING;
+ }
- AFD_DbgPrint(MAX_TRACE, ("Send successful.\n"));
+ /* Return Number of bytes Sent */
+ *lpNumberOfBytesSent = (DWORD)IOSB->Information;
- return 0;
+ /* Success */
+ return STATUS_SUCCESS;
}
+int
+WSPAPI
+WSPSendTo(
+ SOCKET Handle,
+ LPWSABUF lpBuffers,
+ DWORD dwBufferCount,
+ LPDWORD lpNumberOfBytesSent,
+ DWORD iFlags,
+ struct sockaddr *SocketAddress,
+ int SocketAddressLength,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
+ LPWSATHREADID lpThreadId,
+ LPINT lpErrno)
+{
+ PIO_STATUS_BLOCK IOSB;
+ IO_STATUS_BLOCK DummyIOSB;
+ AFD_SEND_INFO_UDP SendInfo;
+ PSOCKET_INFORMATION Socket;
+ NTSTATUS Status;
+ PVOID APCContext;
+ PVOID APCFunction;
+ HANDLE Event;
+ PTRANSPORT_ADDRESS RemoteAddress;
+ UCHAR TdiBuffer[0x16];
+ PSOCKADDR BindAddress;
+ INT BindAddressLength;
+
+ /* Get the Socket Structure associate to this Socket*/
+ Socket = GetSocketStructure(Handle);
+
+ /* Bind us First */
+ if (Socket->SharedData.State == SocketOpen) {
+
+ /* Get the Wildcard Address */
+ BindAddressLength = Socket->HelperData->MaxWSAddressLength;
+ BindAddress = HeapAlloc(GlobalHeap, 0, BindAddressLength);
+ Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext,
+ BindAddress,
+ &BindAddressLength);
+
+ /* Bind it */
+ WSPBind(Handle, BindAddress, BindAddressLength, NULL);
+ }
+
+ /* Set up Address in TDI Format */
+ RemoteAddress = (PTRANSPORT_ADDRESS)TdiBuffer;
+ RemoteAddress->TAAddressCount = 1;
+ RemoteAddress->Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family);
+ RtlCopyMemory(&RemoteAddress->Address[0].AddressType, SocketAddress, SocketAddressLength);
+
+ /* Set up Structure */
+ SendInfo.BufferArray = (PAFD_WSABUF)lpBuffers;
+ SendInfo.AfdFlags = 0;
+ SendInfo.BufferCount = dwBufferCount;
+ SendInfo.RemoteAddress = RemoteAddress;
+ SendInfo.SizeOfRemoteAddress = Socket->HelperData->MaxTDIAddressLength;
+
+ /* Verifiy if we should use APC */
+ if (lpOverlapped == NULL) {
+
+ /* Not using Overlapped structure, so use normal blocking on event */
+ APCContext = NULL;
+ APCFunction = NULL;
+ Event = SockEvent;
+ IOSB = &DummyIOSB;
+
+ } else {
+
+ if (lpCompletionRoutine == NULL) {
+
+ /* Using Overlapped Structure, but no Completition Routine, so no need for APC */
+ APCContext = lpOverlapped;
+ APCFunction = NULL;
+ Event = lpOverlapped->hEvent;
+
+ } else {
+
+ /* Using Overlapped Structure and a Completition Routine, so use an APC */
+ APCFunction = NULL; // should be a private io completition function inside us
+ APCContext = lpCompletionRoutine;
+ SendInfo.AfdFlags = AFD_SKIP_FIO;
+ }
+
+ IOSB = (PIO_STATUS_BLOCK)&lpOverlapped->Internal;
+ SendInfo.AfdFlags |= AFD_OVERLAPPED;
+ }
+
+ /* Send IOCTL */
+ Status = NtDeviceIoControlFile((HANDLE)Handle,
+ SockEvent,
+ APCFunction,
+ APCContext,
+ IOSB,
+ IOCTL_AFD_SEND_DATAGRAM,
+ &SendInfo,
+ sizeof(SendInfo),
+ NULL,
+ 0);
+
+ /* Wait for completition of not overlapped */
+ if (Status == STATUS_PENDING && lpOverlapped == NULL) {
+ WaitForSingleObject(SockEvent, 0); // BUGBUG, shouldn wait infintely for send...
+ Status = IOSB->Status;
+ }
+ if (Status == STATUS_PENDING) {
+ return WSA_IO_PENDING;
+ }
+
+ /* Return Number of bytes Sent */
+ *lpNumberOfBytesSent = (DWORD)IOSB->Information;
+
+ /* Success */
+ return STATUS_SUCCESS;
+}
INT
WSPAPI
-WSPSendDisconnect(
+WSPRecvDisconnect(
IN SOCKET s,
- IN LPWSABUF lpOutboundDisconnectData,
+ OUT LPWSABUF lpInboundDisconnectData,
OUT LPINT lpErrno)
{
UNIMPLEMENTED
@@ -280,75 +523,15 @@
}
+
INT
WSPAPI
-WSPSendTo(
+WSPSendDisconnect(
IN SOCKET s,
- IN LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesSent,
- IN DWORD dwFlags,
- IN CONST LPSOCKADDR lpTo,
- IN INT iToLen,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
- IN LPWSATHREADID lpThreadId,
+ IN LPWSABUF lpOutboundDisconnectData,
OUT LPINT lpErrno)
{
- PFILE_REQUEST_SENDTO Request;
- FILE_REPLY_SENDTO Reply;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- DWORD Size;
-
- AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- Size = dwBufferCount * sizeof(WSABUF);
-
- Request = (PFILE_REQUEST_SENDTO)HeapAlloc(
- GlobalHeap, 0, sizeof(FILE_REQUEST_SENDTO) + Size);
- if (!Request) {
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- /* Put buffer pointers after request structure */
- Request->Buffers = (LPWSABUF)(Request + 1);
- Request->BufferCount = dwBufferCount;
- Request->Flags = dwFlags;
- Request->ToLen = iToLen;
-
- RtlCopyMemory(&Request->To, lpTo, sizeof(SOCKADDR));
-
- RtlCopyMemory(Request->Buffers, lpBuffers, Size);
-
- Status = NtDeviceIoControlFile(
- (HANDLE)s,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_AFD_SENDTO,
- Request,
- sizeof(FILE_REQUEST_SENDTO) + Size,
- &Reply,
- sizeof(FILE_REPLY_SENDTO));
-
- HeapFree(GlobalHeap, 0, Request);
-
- if (Status == STATUS_PENDING) {
- AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
- /* FIXME: Wait only for blocking sockets */
- Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
- }
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
-
- AFD_DbgPrint(MAX_TRACE, ("Send successful.\n"));
+ UNIMPLEMENTED
return 0;
}
reactos/lib/msafd/misc
diff -u -r1.3 -r1.4
--- stubs.c 10 Feb 2004 17:12:42 -0000 1.3
+++ stubs.c 18 Jul 2004 22:49:17 -0000 1.4
@@ -152,20 +152,6 @@
return 0;
}
-
-INT
-WSPAPI
-WSPShutdown(
- IN SOCKET s,
- IN INT how,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
INT
WSPAPI
WSPStringToAddress(
reactos/drivers/net/tcpip/tcpip
diff -u -r1.28 -r1.29
--- main.c 18 Jul 2004 22:03:49 -0000 1.28
+++ main.c 18 Jul 2004 22:49:18 -0000 1.29
@@ -20,7 +20,7 @@
#include <info.h>
#include <memtrack.h>
-//#define NDEBUG
+#define NDEBUG
#ifndef NDEBUG
DWORD DebugTraceLevel = 0x7fffffff;
CVSspam 0.2.8