diff --git a/reactos/drivers/net/afd/afd/afd.c b/reactos/drivers/net/afd/afd/afd.c deleted file mode 100644 index e5d89842a66..00000000000 --- a/reactos/drivers/net/afd/afd/afd.c +++ /dev/null @@ -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 -#include - -#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 */ diff --git a/reactos/drivers/net/afd/afd/bind.c b/reactos/drivers/net/afd/afd/bind.c new file mode 100644 index 00000000000..629b64a7938 --- /dev/null +++ b/reactos/drivers/net/afd/afd/bind.c @@ -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 ); +} + diff --git a/reactos/drivers/net/afd/afd/connect.c b/reactos/drivers/net/afd/afd/connect.c new file mode 100644 index 00000000000..b11f15065c1 --- /dev/null +++ b/reactos/drivers/net/afd/afd/connect.c @@ -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 ); +} diff --git a/reactos/drivers/net/afd/afd/context.c b/reactos/drivers/net/afd/afd/context.c new file mode 100644 index 00000000000..ecc1515d8d8 --- /dev/null +++ b/reactos/drivers/net/afd/afd/context.c @@ -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 ); +} diff --git a/reactos/drivers/net/afd/afd/dispatch.c b/reactos/drivers/net/afd/afd/dispatch.c deleted file mode 100644 index 70bcc086339..00000000000 --- a/reactos/drivers/net/afd/afd/dispatch.c +++ /dev/null @@ -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 - -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; - } - FileObject = FCB->TdiConnectionObject; - } else { - FileObject = FCB->TdiAddressObject; - } - - AddressInfoSize = sizeof(TDI_ADDRESS_INFO) + sizeof(TDI_ADDRESS_IP); - AddressInfoBuffer = ExAllocatePool(NonPagedPool, AddressInfoSize); - - Mdl = IoAllocateMdl( - AddressInfoBuffer, /* Virtual address of buffer */ - AddressInfoSize, /* Length of buffer */ - FALSE, /* Not secondary */ - FALSE, /* Don't charge quota */ - NULL); /* Don't use IRP */ - - if (!Mdl) { - ExFreePool(AddressInfoBuffer); - return STATUS_INSUFFICIENT_RESOURCES; - } - - MmBuildMdlForNonPagedPool(Mdl); - - Status = TdiQueryInformation( - FileObject, - TDI_QUERY_ADDRESS_INFO, - Mdl); - - if (NT_SUCCESS(Status)) { - Reply->Name.sa_family = AddressInfoBuffer->Address.Address[0].AddressType; - - RtlCopyMemory( - Reply->Name.sa_data, - AddressInfoBuffer->Address.Address[0].Address, - sizeof(Reply->Name.sa_data)); - - Reply->NameSize = sizeof(Reply->Name.sa_family) + - AddressInfoBuffer->Address.Address[0].AddressLength; - } - - IoFreeMdl(Mdl); - ExFreePool(AddressInfoBuffer); - } - - AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status)); - - return Status; -} - -/* EOF */ diff --git a/reactos/drivers/net/afd/afd/info.c b/reactos/drivers/net/afd/afd/info.c new file mode 100644 index 00000000000..82141673ade --- /dev/null +++ b/reactos/drivers/net/afd/afd/info.c @@ -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 ); +} diff --git a/reactos/drivers/net/afd/afd/listen.c b/reactos/drivers/net/afd/afd/listen.c new file mode 100644 index 00000000000..90cc5d8ee93 --- /dev/null +++ b/reactos/drivers/net/afd/afd/listen.c @@ -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 ); +} diff --git a/reactos/drivers/net/afd/afd/lock.c b/reactos/drivers/net/afd/afd/lock.c new file mode 100644 index 00000000000..ddeb64b81a7 --- /dev/null +++ b/reactos/drivers/net/afd/afd/lock.c @@ -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 ); +} + diff --git a/reactos/drivers/net/afd/afd/main.c b/reactos/drivers/net/afd/afd/main.c new file mode 100644 index 00000000000..c609836abbb --- /dev/null +++ b/reactos/drivers/net/afd/afd/main.c @@ -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 */ diff --git a/reactos/drivers/net/afd/afd/opnclose.c b/reactos/drivers/net/afd/afd/opnclose.c deleted file mode 100644 index 7e28a37c35a..00000000000 --- a/reactos/drivers/net/afd/afd/opnclose.c +++ /dev/null @@ -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 - -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 */ diff --git a/reactos/drivers/net/afd/afd/rdwr.c b/reactos/drivers/net/afd/afd/rdwr.c deleted file mode 100644 index 9c2ccc999f9..00000000000 --- a/reactos/drivers/net/afd/afd/rdwr.c +++ /dev/null @@ -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 - -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 */ diff --git a/reactos/drivers/net/afd/afd/read.c b/reactos/drivers/net/afd/afd/read.c new file mode 100644 index 00000000000..7a39b40b05b --- /dev/null +++ b/reactos/drivers/net/afd/afd/read.c @@ -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 ); + } +} diff --git a/reactos/drivers/net/afd/afd/routines.c b/reactos/drivers/net/afd/afd/routines.c deleted file mode 100644 index a0812cc87d1..00000000000 --- a/reactos/drivers/net/afd/afd/routines.c +++ /dev/null @@ -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 -#include - -#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 */ diff --git a/reactos/drivers/net/afd/afd/select.c b/reactos/drivers/net/afd/afd/select.c new file mode 100644 index 00000000000..761f37b3400 --- /dev/null +++ b/reactos/drivers/net/afd/afd/select.c @@ -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")); +} diff --git a/reactos/drivers/net/afd/afd/tdi.c b/reactos/drivers/net/afd/afd/tdi.c index 067d1f46d63..5e0bee8772b 100644 --- a/reactos/drivers/net/afd/afd/tdi.c +++ b/reactos/drivers/net/afd/afd/tdi.c @@ -8,6 +8,7 @@ * CSH 01/09-2000 Created */ #include +#include "debug.h" #include "tdiconn.h" #ifdef DBG @@ -57,10 +58,12 @@ NTSTATUS TdiCall( { 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 @@ NTSTATUS TdiOpenDevice( 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 @@ NTSTATUS TdiOpenDevice( 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 TdiCloseDevice( } -NTSTATUS TdiOpenAddressFileIPv4( +NTSTATUS TdiOpenAddressFile( PUNICODE_STRING DeviceName, - LPSOCKADDR Name, + PTRANSPORT_ADDRESS Name, PHANDLE AddressHandle, PFILE_OBJECT *AddressObject) /* @@ -175,21 +178,21 @@ NTSTATUS TdiOpenAddressFileIPv4( */ { 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 @@ NTSTATUS TdiOpenAddressFileIPv4( 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 TdiOpenAddressFileIPv4( } -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 TdiOpenConnectionEndpointFile( 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 @@ NTSTATUS TdiConnect( IO_STATUS_BLOCK Iosb; NTSTATUS Status; KEVENT Event; - PIRP Irp; AFD_DbgPrint(MAX_TRACE, ("Called\n")); @@ -323,12 +291,17 @@ NTSTATUS TdiConnect( 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 @@ NTSTATUS TdiConnect( 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 TdiAssociateAddressFile( } -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 @@ NTSTATUS TdiListen( * 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 @@ NTSTATUS TdiQueryInformation( return Status; } - +#if 0 NTSTATUS TdiQueryInformationEx( PFILE_OBJECT FileObject, ULONG Entity, @@ -672,7 +639,6 @@ NTSTATUS TdiQueryInformationEx( OutputLength); /* Return information */ } - NTSTATUS TdiQueryAddress( PFILE_OBJECT FileObject, PULONG Address) @@ -806,31 +772,20 @@ NTSTATUS TdiQueryAddress( 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 @@ NTSTATUS TdiSend( return STATUS_INVALID_PARAMETER; } - Status = TdiBuildConnectionInfo( &ConnectInfo, Address ); - if (!NT_SUCCESS(Status)) - return STATUS_INSUFFICIENT_RESOURCES; + *Irp = TdiBuildInternalDeviceControlIrp + ( TDI_SEND, /* Sub function */ + DeviceObject, /* Device object */ + TransportObject, /* File object */ + NULL, /* Event */ + Iosb ); /* Status */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - 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,44 @@ DisplayBuffer(Request->Buffers->buf, Request->Buffers->len); #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 */ - 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 */ - - Status = TdiCall(Irp, DeviceObject, &Event, &Iosb); - - MmUnmapLockedPages(BaseAddress, Mdl); - - MmUnlockPages(Mdl); - - IoFreeMdl(Mdl); - - ExFreePool(ConnectInfo); + Status = TdiCall(*Irp, DeviceObject, NULL, Iosb); + /* Does not block... The MDL is deleted in the receive completion + routine. */ return Status; -#endif - return STATUS_SUCCESS; } - -NTSTATUS TdiSendDatagram( +NTSTATUS TdiReceive( + PIRP *Irp, PFILE_OBJECT TransportObject, - LPSOCKADDR Address, - PMDL Mdl, - ULONG BufferSize) -/* - * FUNCTION: Sends 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 - * RETURNS: - * Status of operation - */ + USHORT Flags, + PCHAR Buffer, + UINT BufferLength, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext) { - 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,89 +869,73 @@ NTSTATUS TdiSendDatagram( return STATUS_INVALID_PARAMETER; } - AFD_DbgPrint(MAX_TRACE, - ("TdiSendDatagram: TansportObject = %08x\n", TransportObject)); + *Irp = TdiBuildInternalDeviceControlIrp + ( TDI_RECEIVE, /* Sub function */ + DeviceObject, /* Device object */ + TransportObject, /* File object */ + NULL, /* Event */ + Iosb ); /* Status */ - TdiBuildConnectionInfo( &ConnectInfo, Address ); - - AFD_DbgPrint(MAX_TRACE, ("Point B\n")); - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - AFD_DbgPrint(MAX_TRACE, ("Point 0\n")); - - 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")); + AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); - Status = TdiCall(Irp, DeviceObject, &Event, &Iosb); - AFD_DbgPrint(MAX_TRACE, ("Returned from TdiCall\n")); + 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 */ -#if 0 - MmUnlockPages(Mdl); - - IoFreeMdl(Mdl); -#endif - - ExFreePool(ConnectInfo); - AFD_DbgPrint(MAX_TRACE, ("Leaving %08x.\n", Status)); + Status = TdiCall(*Irp, DeviceObject, NULL, Iosb); + /* Does not block... The MDL is deleted in the receive completion + routine. */ return Status; } NTSTATUS TdiReceiveDatagram( + PIRP *Irp, PFILE_OBJECT TransportObject, - LPSOCKADDR From, - LPSOCKADDR Address, - PUCHAR Buffer, - PULONG BufferSize) + USHORT Flags, + PCHAR Buffer, + UINT BufferLength, + PTDI_CONNECTION_INFORMATION Addr, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext) /* * FUNCTION: Receives a datagram * ARGUMENTS: @@ -1043,49 +948,38 @@ NTSTATUS TdiReceiveDatagram( * 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_RECEIVE_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 +991,117 @@ NTSTATUS TdiReceiveDatagram( } 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)); + AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); + + 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 TdiSendDatagram( + PIRP *Irp, + PFILE_OBJECT TransportObject, + PCHAR Buffer, + UINT BufferLength, + PTDI_CONNECTION_INFORMATION Addr, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext) +/* + * FUNCTION: Sends a datagram + * ARGUMENTS: + * TransportObject = Pointer to transport object + * From = Send filter (NULL if none) + * Address = Address of buffer to place remote address + * Buffer = Address of buffer to place sendd data + * BufferSize = Address of buffer with length of Buffer (updated) + * RETURNS: + * Status of operation + */ +{ + PDEVICE_OBJECT DeviceObject; + NTSTATUS Status; + PMDL Mdl; + + DeviceObject = IoGetRelatedDeviceObject(TransportObject); + if (!DeviceObject) { + AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); + return STATUS_INVALID_PARAMETER; } - MmUnlockPages(Mdl); + *Irp = TdiBuildInternalDeviceControlIrp + ( TDI_SEND_DATAGRAM, /* 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(ReceiveInfo); + AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); + + 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 + 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)); + + 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; } diff --git a/reactos/drivers/net/afd/afd/tdiconn.c b/reactos/drivers/net/afd/afd/tdiconn.c index 0e4f6e8d8ed..d4d2c502428 100644 --- a/reactos/drivers/net/afd/afd/tdiconn.c +++ b/reactos/drivers/net/afd/afd/tdiconn.c @@ -1,191 +1,63 @@ +/* $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 +#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; +UINT TdiAddressSizeFromType( UINT AddressType ) { + switch( AddressType ) { + case TDI_ADDRESS_TYPE_IP: + return sizeof(TA_IP_ADDRESS); + default: + KeBugCheck( 0 ); + } + 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 TaLengthOfAddress( PTA_ADDRESS Addr ) { + UINT AddrLen = 2 * sizeof( USHORT ) + Addr->AddressLength; + AFD_DbgPrint(MID_TRACE,("AddrLen %x\n", AddrLen)); + return AddrLen; } - -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 TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ) { + UINT AddrLen = 2 * sizeof( ULONG ) + Addr->Address[0].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; +VOID TaCopyAddressInPlace( PTA_ADDRESS Target, + PTA_ADDRESS Source ) { + UINT AddrLen = TaLengthOfAddress( Source ); + RtlCopyMemory( Target, Source, 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 TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target, + PTRANSPORT_ADDRESS Source ) { + UINT AddrLen = TaLengthOfTransportAddress( 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; +PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ) { + UINT AddrLen; + PTRANSPORT_ADDRESS A; - TdiAddressSize = TdiAddressSizeFromName(Name); + ASSERT(OtherAddress->TAAddressCount == 1); + AddrLen = TaLengthOfTransportAddress( OtherAddress ); + A = ExAllocatePool( NonPagedPool, AddrLen ); - RtlZeroMemory(ConnInfo, - sizeof(TDI_CONNECTION_INFORMATION) + - TdiAddressSize); + if( A ) + TaCopyTransportAddressInPlace( A, OtherAddress ); - ConnInfo->OptionsLength = sizeof(ULONG); - ConnInfo->RemoteAddressLength = TdiAddressSize; - ConnInfo->RemoteAddress = (PVOID) - (((PCHAR)ConnInfo) + sizeof(TDI_CONNECTION_INFORMATION)); - - TdiBuildAddress(ConnInfo->RemoteAddress, Name); - - return STATUS_SUCCESS; + return A; } - - -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; - - Status = TdiBuildConnectionInfoInPlace( ConnInfo, Name ); - - if( !NT_SUCCESS(Status) ) - ExFreePool( ConnInfo ); - else - *ConnectionInfo = ConnInfo; - - return Status; -} - NTSTATUS TdiBuildNullConnectionInfoInPlace ( PTDI_CONNECTION_INFORMATION ConnInfo, @@ -204,8 +76,8 @@ NTSTATUS TdiBuildNullConnectionInfoInPlace 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 @@ NTSTATUS TdiBuildNullConnectionInfo 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 @@ NTSTATUS TdiBuildNullConnectionInfo 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 @@ TdiBuildConnectionInfoPair */ { 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 @@ TdiBuildConnectionInfoPair 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; } diff --git a/reactos/drivers/net/afd/afd/write.c b/reactos/drivers/net/afd/afd/write.c new file mode 100644 index 00000000000..4aea7b8ce23 --- /dev/null +++ b/reactos/drivers/net/afd/afd/write.c @@ -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 ); +} + diff --git a/reactos/drivers/net/afd/doc/simple_select.txt b/reactos/drivers/net/afd/doc/simple_select.txt new file mode 100644 index 00000000000..a00fd1c0c3a --- /dev/null +++ b/reactos/drivers/net/afd/doc/simple_select.txt @@ -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 + diff --git a/reactos/drivers/net/afd/include/afd.h b/reactos/drivers/net/afd/include/afd.h index 2e1c2899ddb..ad443f0de8a 100644 --- a/reactos/drivers/net/afd/include/afd.h +++ b/reactos/drivers/net/afd/include/afd.h @@ -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 +#ifndef _AFD_H +#define _AFD_H + +#include +#include +#include +#include +#include +#include +#include + +#ifndef _MSC_VER +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#else +#include +#define STDCALL +#endif -#define IP_MIB_STATS_ID 1 -#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102 +#ifndef MIN +#define MIN(x,y) (((x)<(y))?(x):(y)) +#endif -/* Forward declarations */ -struct _AFDFCB; +#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 -typedef struct _DEVICE_EXTENSION { - PDEVICE_OBJECT StorageDevice; - KSPIN_LOCK FCBListLock; - LIST_ENTRY FCBListHead; -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; +#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 -/* Context Control Block structure */ -typedef struct _AFDCCB { - struct _AFDFCB *FCB; - LIST_ENTRY ListEntry; - PFILE_OBJECT FileObject; - ULONG Flags; - LARGE_INTEGER CurrentByteOffset; -} AFDCCB, *PAFDCCB; +#define IN_FLIGHT_REQUESTS 3 -/* Flags for CCB structure */ -#define CCB_CLEANED 0x00000001 +#define DEFAULT_SEND_WINDOW_SIZE 16384 +#define DEFAULT_RECEIVE_WINDOW_SIZE 16384 -typedef struct _FsdNTRequiredFCB { - FSRTL_COMMON_FCB_HEADER CommonFCBHeader; - SECTION_OBJECT_POINTERS SectionObject; - ERESOURCE MainResource; - ERESOURCE PagingIoResource; -} FsdNTRequiredFCB, *PFsdNTRequiredFCB; +#define SGID_CONNECTIONLESS 1 /* XXX Find this flag */ -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; +typedef struct _AFD_MAPBUF { + PVOID BufferAddress; + PMDL Mdl; +} AFD_MAPBUF, *PAFD_MAPBUF; -/* 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_DEVICE_EXTENSION { + PDEVICE_OBJECT DeviceObject; + LIST_ENTRY Polls; + KSPIN_LOCK Lock; +} AFD_DEVICE_EXTENSION, *PAFD_DEVICE_EXTENSION; -typedef struct _AFD_BUFFER { - LIST_ENTRY ListEntry; - WSABUF Buffer; - UINT Offset; -} AFD_BUFFER, *PAFD_BUFFER; +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 _AFD_READ_REQUEST { - LIST_ENTRY ListEntry; - PIRP Irp; - PFILE_REQUEST_RECVFROM RecvFromRequest; - PFILE_REPLY_RECVFROM RecvFromReply; -} AFD_READ_REQUEST, *PAFD_READ_REQUEST; +typedef struct _IRP_LIST { + LIST_ENTRY ListEntry; + PIRP Irp; +} IRP_LIST, *PIRP_LIST; -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 _AFD_TDI_OBJECT { + PFILE_OBJECT Object; + HANDLE Handle; +} AFD_TDI_OBJECT, *PAFD_TDI_OBJECT; -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 _AFD_IN_FLIGHT_REQUEST { + PIRP InFlightRequest; + IO_STATUS_BLOCK Iosb; + PTDI_CONNECTION_INFORMATION ConnectionInfo; +} AFD_IN_FLIGHT_REQUEST, *PAFD_IN_FLIGHT_REQUEST; -typedef struct IPADDR_ENTRY { - ULONG Addr; - ULONG Index; - ULONG Mask; - ULONG BcastAddr; - ULONG ReasmSize; - USHORT Context; - USHORT Pad; -} IPADDR_ENTRY, *PIPADDR_ENTRY; +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; -#define TL_INSTANCE 0 +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; -/* 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; +/* bind.c */ +NTSTATUS WarmSocketForBind( PAFD_FCB FCB ); +NTSTATUS STDCALL +AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp); -/* IOCTL codes */ +/* connect.c */ -#define IOCTL_TCP_QUERY_INFORMATION_EX \ - CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS) +NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ); +NTSTATUS STDCALL +AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp); -#define IOCTL_TCP_SET_INFORMATION_EX \ - CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS) +/* 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 ); -#ifdef i386 +/* info.c */ -/* DWORD network to host byte order conversion for i386 */ -#define DN2H(dw) \ - ((((dw) & 0xFF000000L) >> 24) | \ - (((dw) & 0x00FF0000L) >> 8) | \ - (((dw) & 0x0000FF00L) << 8) | \ - (((dw) & 0x000000FFL) << 24)) +NTSTATUS STDCALL +AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp ); -/* DWORD host to network byte order conversion for i386 */ -#define DH2N(dw) \ - ((((dw) & 0xFF000000L) >> 24) | \ - (((dw) & 0x00FF0000L) >> 8) | \ - (((dw) & 0x0000FF00L) << 8) | \ - (((dw) & 0x000000FFL) << 24)) +/* listen.c */ -/* WORD network to host order conversion for i386 */ -#define WN2H(w) \ - ((((w) & 0xFF00) >> 8) | \ - (((w) & 0x00FF) << 8)) +NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, + PIO_STACK_LOCATION IrpSp); -/* WORD host to network byte order conversion for i386 */ -#define WH2N(w) \ - ((((w) & 0xFF00) >> 8) | \ - (((w) & 0x00FF) << 8)) +/* lock.c */ -#else /* i386 */ +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 ); -/* DWORD network to host byte order conversion for other architectures */ -#define DN2H(dw) \ - (dw) +/* main.c */ -/* DWORD host to network byte order conversion for other architectures */ -#define DH2N(dw) \ - (dw) +VOID OskitDumpBuffer( PCHAR Buffer, UINT Len ); +NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ); -/* WORD network to host order conversion for other architectures */ -#define WN2H(w) \ - (w) +/* read.c */ -/* 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); - -NTSTATUS AfdDispEventSelect( +NTSTATUS DDKAPI ReceiveComplete +( PDEVICE_OBJECT DeviceObject, PIRP Irp, - PIO_STACK_LOCATION IrpSp); + PVOID Context ); -NTSTATUS AfdDispEnumNetworkEvents( - PIRP Irp, - PIO_STACK_LOCATION IrpSp); - -NTSTATUS AfdDispRecv( - PIRP Irp, - PIO_STACK_LOCATION IrpSp); - -NTSTATUS AfdDispSend( - PIRP Irp, - PIO_STACK_LOCATION IrpSp); - -NTSTATUS AfdDispConnect( +NTSTATUS DDKAPI PacketSocketRecvComplete +( PDEVICE_OBJECT DeviceObject, PIRP Irp, - PIO_STACK_LOCATION IrpSp); + PVOID Context ); -NTSTATUS AfdDispGetName( - PIRP Irp, - PIO_STACK_LOCATION IrpSp); +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 ); -/* Prototypes from event.c */ +/* select.c */ -NTSTATUS AfdRegisterEventHandlers( - PAFDFCB FCB); +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 TdiSetEventHandler( - PFILE_OBJECT FileObject, - LONG EventType, - PVOID Handler, - PVOID Context); +NTSTATUS TdiReceive +( PIRP *Irp, + PFILE_OBJECT ConnectionObject, + USHORT Flags, + PCHAR Buffer, + UINT BufferLength, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext); -NTSTATUS TdiQueryInformation( - PFILE_OBJECT FileObject, - LONG QueryType, - PMDL MdlBuffer); +NTSTATUS TdiSend +( PIRP *Irp, + PFILE_OBJECT ConnectionObject, + USHORT Flags, + PCHAR Buffer, + UINT BufferLength, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext); -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); + PIRP *Irp, + PFILE_OBJECT TransportObject, + PCHAR Buffer, + UINT BufferLength, + PTDI_CONNECTION_INFORMATION To, + PIO_STATUS_BLOCK Iosb, + PIO_COMPLETION_ROUTINE CompletionRoutine, + PVOID CompletionContext); -#endif /*__AFD_H */ +/* write.c */ -/* EOF */ +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); + +#endif/*_AFD_H*/ diff --git a/reactos/drivers/net/afd/include/tdi_proto.h b/reactos/drivers/net/afd/include/tdi_proto.h new file mode 100644 index 00000000000..bd260a1a91a --- /dev/null +++ b/reactos/drivers/net/afd/include/tdi_proto.h @@ -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*/ diff --git a/reactos/drivers/net/afd/include/tdiconn.h b/reactos/drivers/net/afd/include/tdiconn.h index 2e6158d24c0..2eb21b5bba4 100644 --- a/reactos/drivers/net/afd/include/tdiconn.h +++ b/reactos/drivers/net/afd/include/tdiconn.h @@ -2,27 +2,30 @@ #define _TDICONN_H #include +#ifdef _MSC_VER +#include +#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*/ diff --git a/reactos/drivers/net/afd/makefile b/reactos/drivers/net/afd/makefile index 5503939ca1b..ced5c3c619b 100644 --- a/reactos/drivers/net/afd/makefile +++ b/reactos/drivers/net/afd/makefile @@ -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_TYPE = driver 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 diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index a8a61d8d01f..0d92ef46bb4 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -20,7 +20,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #ifndef NDEBUG DWORD DebugTraceLevel = 0x7fffffff; diff --git a/reactos/lib/msafd/include/helpers.h b/reactos/lib/msafd/include/helpers.h index a4647ec5fa2..f8396b7c05b 100644 --- a/reactos/lib/msafd/include/helpers.h +++ b/reactos/lib/msafd/include/helpers.h @@ -9,53 +9,64 @@ #include -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 _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; -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; +int SockLoadHelperDll( + PWSTR TransportName, + PWINSOCK_MAPPING Mapping, + PHELPER_DATA *HelperDllData +); +int SockLoadTransportMapping( + PWSTR TransportName, + PWINSOCK_MAPPING *Mapping +); -PWSHELPER_DLL CreateHelperDLL( - LPWSTR LibraryName); +int SockLoadTransportList( + PWSTR *TransportList +); -INT DestroyHelperDLL( - PWSHELPER_DLL HelperDLL); +BOOL SockIsTripleInMapping( + PWINSOCK_MAPPING Mapping, + INT AddressFamily, + INT SocketType, + INT Protocol +); -PWSHELPER_DLL LocateHelperDLL( - LPWSAPROTOCOL_INFOW lpProtocolInfo); - -INT LoadHelperDLL( - PWSHELPER_DLL HelperDLL); - -INT UnloadHelperDLL( - PWSHELPER_DLL HelperDLL); - -VOID CreateHelperDLLDatabase(VOID); - -VOID DestroyHelperDLLDatabase(VOID); +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 */ diff --git a/reactos/lib/msafd/include/msafd.h b/reactos/lib/msafd/include/msafd.h index d7bfd1bcfe7..2ca90fe3934 100644 --- a/reactos/lib/msafd/include/msafd.h +++ b/reactos/lib/msafd/include/msafd.h @@ -11,23 +11,102 @@ #include #include #include -#include +#include /* comment for msvc */ +//#include "C:\Programming\ReactOS\reactos\w32api\include\wsahelp.h" uncomment for MSVC #include #include -#include +//#include "C:\Programming\ReactOS\reactos\w32api\include\ddk\tdi.h" uncomment for MSVC +#include /* comment for msvc */ #include +#include #include -/*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 @@ WSPStringToAddress( 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 */ diff --git a/reactos/lib/msafd/makefile b/reactos/lib/msafd/makefile index e3e1d55edad..075bec5ea9e 100644 --- a/reactos/lib/msafd/makefile +++ b/reactos/lib/msafd/makefile @@ -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_NAME = msafd TARGET_BASE = $(TARGET_BASE_LIB_MSAFD) -TARGET_SDKLIBS = ntdll.a kernel32.a +TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a TARGET_CFLAGS = \ -I./include \ diff --git a/reactos/lib/msafd/misc/dllmain.c b/reactos/lib/msafd/misc/dllmain.c index f465cda274a..3c773d32cd3 100644 --- a/reactos/lib/msafd/misc/dllmain.c +++ b/reactos/lib/msafd/misc/dllmain.c @@ -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 #include @@ -13,146 +15,30 @@ #include #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; +HANDLE SockEvent; +ULONG SocketCount; +PSOCKET_INFORMATION *Sockets = NULL; +LIST_ENTRY SockHelpersListHead = {NULL}; - -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); - - 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 @@ WSPSocket( * 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; + 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, ("af (%d) type (%d) protocol (%d).\n", - af, type, protocol)); + AFD_DbgPrint(MAX_TRACE, ("Creating Socket, getting TDI Name\n")); + AFD_DbgPrint(MAX_TRACE, ("AddressFamily (%d) SocketType (%d) Protocol (%d).\n", + AddressFamily, SocketType, Protocol)); - if (!lpProtocolInfo) { - lpProtocolInfo = &ProtocolInfo; - ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW)); + /* Get Helper Data and Transport */ + Status = SockGetTdiName (&AddressFamily, + &SocketType, + &Protocol, + g, + dwFlags, + &TransportName, + &HelperDLLContext, + &HelperData, + &HelperEvents); - ProtocolInfo.iAddressFamily = af; - ProtocolInfo.iSocketType = type; - ProtocolInfo.iProtocol = protocol; - } + /* 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; + /* 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; - /* 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; - } + /* Packet Size */ + SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET) + sizeof(WCHAR); - NtStatus = OpenSocket(&Socket, - AddressFamily, - SocketType, - Protocol, - HelperContext, - NotificationEvents, - &TdiDeviceName); + /* EA Size */ + SizeOfEA = SizeOfPacket + sizeof(FILE_FULL_EA_INFORMATION) + AFD_PACKET_COMMAND_LENGTH; - RtlFreeUnicodeString(&TdiDeviceName); - if (!NT_SUCCESS(NtStatus)) { - *lpErrno = RtlNtStatusToDosError(Status); - return INVALID_SOCKET; - } + /* 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; - /* FIXME: Assumes catalog entry id to be 1 */ - Socket2 = Upcalls.lpWPUModifyIFSHandle(1, Socket, lpErrno); + /* 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; + } - if (Socket2 == INVALID_SOCKET) { - /* FIXME: Cleanup */ - AFD_DbgPrint(MIN_TRACE, ("FIXME: Cleanup.\n")); - return INVALID_SOCKET; - } + if (SocketType == SOCK_RAW) AfdPacket->EndpointFlags |= AFD_ENDPOINT_RAW; - *lpErrno = NO_ERROR; + 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; + } + } - AFD_DbgPrint(MID_TRACE, ("Returning socket descriptor (0x%X).\n", Socket2)); + /* Set up Object Attributes */ + InitializeObjectAttributes (&Object, + &DevName, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + 0, + 0); - return Socket2; + /* 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); + + 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); + + /* Return Socket Handle */ + return (SOCKET)Sock; + +error: + AFD_DbgPrint(MID_TRACE,("Ending\n")); + + return 0; } @@ -277,29 +264,17 @@ WSPCloseSocket( * 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 @@ WSPBind( * 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; + IO_STATUS_BLOCK IOSB; + PAFD_BIND_DATA BindData; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + UCHAR BindBuffer[0x1A]; + SOCKADDR_INFO SocketInfo; - AFD_DbgPrint(MAX_TRACE, ("s (0x%X) name (0x%X) namelen (%d).\n", s, name, namelen)); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - RtlCopyMemory(&Request.Name, name, sizeof(SOCKADDR)); + /* Dynamic Structure...ugh */ + BindData = (PAFD_BIND_DATA)BindBuffer; - 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); - } + /* 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); - if (!NT_SUCCESS(Status)) { - *lpErrno = Reply.Status; - return SOCKET_ERROR; + /* 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; - AFD_DbgPrint(MAX_TRACE, ("s (0x%X) backlog (%d).\n", s, backlog)); + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); -/* 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; - }*/ + /* Set Up Listen Structure */ + ListenData.UseSAN = FALSE; + ListenData.UseDelayedAcceptance = Socket->SharedData.UseDelayedAcceptance; + ListenData.Backlog = Backlog; - Request.Backlog = backlog; + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_START_LISTEN, + &ListenData, + sizeof(ListenData), + NULL, + 0); - 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; - } + /* Set to Listening */ + Socket->SharedData.Listening = TRUE; - 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; + IO_STATUS_BLOCK IOSB; + PAFD_POLL_INFO PollInfo; + NTSTATUS Status; + ULONG HandleCount; + ULONG PollBufferSize; + LARGE_INTEGER uSec; + PVOID PollBuffer; + ULONG i, j = 0; - 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; - } + /* 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)); - /* FIXME: For now, always allow write */ - if (writefds != NULL) { - AFD_DbgPrint(MID_TRACE, ("Setting one socket writeable.\n")); - *lpErrno = NO_ERROR; - return 1; - } -#endif + /* Allocate */ + PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize); + PollInfo = (PAFD_POLL_INFO)PollBuffer; - ReadSize = 0; - if ((readfds != NULL) && (readfds->fd_count > 0)) { - ReadSize = (readfds->fd_count * sizeof(SOCKET)) + sizeof(UINT); - } + /* 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; - WriteSize = 0; - if ((writefds != NULL) && (writefds->fd_count > 0)) { - WriteSize = (writefds->fd_count * sizeof(SOCKET)) + sizeof(UINT); - } + 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; + } - 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)); - - HeapFree(GlobalHeap, 0, Request); - - 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; + } 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; + } } - AFD_DbgPrint(MAX_TRACE, ("Select successful. Status (0x%X) Count (0x%X).\n", - Reply.Status, Reply.SocketCount)); + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_SELECT, + PollInfo, + PollBufferSize, + PollInfo, + PollBufferSize); - *lpErrno = Reply.Status; + /* Wait for Completition */ + if (Status == STATUS_PENDING) { + WaitForSingleObject(SockEvent, 0); + } - return Reply.SocketCount; + /* 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 0; } SOCKET -WSPAPI +WSPAPI WSPAccept( - IN SOCKET s, - OUT LPSOCKADDR addr, - IN OUT LPINT addrlen, - IN LPCONDITIONPROC lpfnCondition, - IN DWORD dwCallbackData, - OUT LPINT lpErrno) + SOCKET Handle, + struct sockaddr *SocketAddress, + int *SocketAddressLength, + LPCONDITIONPROC lpfnCondition, + DWORD_PTR dwCallbackData, + LPINT lpErrno) { - FILE_REQUEST_ACCEPT Request; - FILE_REPLY_ACCEPT Reply; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; + 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]; - AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s)); + /* Dynamic Structure...ugh */ + ListenReceiveData = (PAFD_RECEIVED_ACCEPT_DATA)ReceiveBuffer; - Request.addr = addr; - Request.addrlen = *addrlen; - Request.lpfnCondition = lpfnCondition; - Request.dwCallbackData = dwCallbackData; + /* 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; - Status = NtDeviceIoControlFile( - (HANDLE)s, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_AFD_ACCEPT, - &Request, - sizeof(FILE_REQUEST_ACCEPT), - &Reply, - sizeof(FILE_REPLY_ACCEPT)); - if (Status == STATUS_PENDING) { - AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n")); - /* FIXME: Wait only for blocking sockets */ - Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL); - } + /* 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) { - if (!NT_SUCCESS(Status)) { - *lpErrno = Reply.Status; - return INVALID_SOCKET; - } + /* Find out how much data is pending */ + PendingAcceptData.SequenceNumber = ListenReceiveData->SequenceNumber; + PendingAcceptData.ReturnSize = TRUE; - *addrlen = Reply.addrlen; + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_PENDING_CONNECT_DATA, + &PendingAcceptData, + sizeof(PendingAcceptData), + &PendingAcceptData, + sizeof(PendingAcceptData)); - return Reply.Socket; + /* How much data to allocate */ + PendingDataLength = IOSB.Information; + + if (PendingDataLength) { + + /* Allocate needed space */ + PendingData = HeapAlloc(GlobalHeap, 0, PendingDataLength); + + /* We want the data now */ + PendingAcceptData.ReturnSize = FALSE; + + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_PENDING_CONNECT_DATA, + &PendingAcceptData, + sizeof(PendingAcceptData), + PendingData, + PendingDataLength); + } + } + + + if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) { + /* I don't support this yet */ + } + + /* Build Callee ID */ + CalleeID.buf = (PVOID)Socket->LocalAddress; + CalleeID.len = Socket->SharedData.SizeOfLocalAddress; + + /* Set up Address in SOCKADDR Format */ + RtlCopyMemory (RemoteAddress, + &ListenReceiveData->Address.Address[0].AddressType, + sizeof(RemoteAddress)); + + /* Build Caller ID */ + CallerID.buf = (PVOID)RemoteAddress; + CallerID.len = sizeof(RemoteAddress); + + /* Build Caller Data */ + CallerData.buf = PendingData; + CallerData.len = PendingDataLength; + + /* Check if socket supports Conditional Accept */ + if (Socket->SharedData.UseDelayedAcceptance != 0) { + + /* Allocate Buffer for Callee Data */ + CalleeDataBuffer = HeapAlloc(GlobalHeap, 0, 4096); + CalleeData.buf = CalleeDataBuffer; + CalleeData.len = 4096; + + } else { + + /* Nothing */ + CalleeData.buf = 0; + CalleeData.len = 0; + } + + /* Call the Condition Function */ + CallBack = (lpfnCondition)( &CallerID, + CallerData.buf == NULL + ? NULL + : & CallerData, + NULL, + NULL, + &CalleeID, + CalleeData.buf == NULL + ? NULL + : & CalleeData, + &GroupID, + dwCallbackData); + + if (((CallBack == CF_ACCEPT) && GroupID) != 0) { + /* TBD: Check for Validity */ + } + + if (CallBack == CF_ACCEPT) { + + if ((Socket->SharedData.ServiceFlags1 & XP1_QOS_SUPPORTED) != 0) { + /* I don't support this yet */ + } + + if (CalleeData.buf) { + // SockSetConnectData Sockets(SocketID), IOCTL_AFD_SET_CONNECT_DATA, CalleeData.Buffer, CalleeData.BuffSize, 0 + } + + } else { + /* Callback rejected. Build Defer Structure */ + DeferData.SequenceNumber = ListenReceiveData->SequenceNumber; + DeferData.RejectConnection = (CallBack == CF_REJECT); + + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_DEFER_ACCEPT, + &DeferData, + sizeof(DeferData), + NULL, + 0); + + if (CallBack == CF_REJECT ) { + return WSAECONNREFUSED; + } else { + return WSATRY_AGAIN; + } + } + } + + /* Create a new Socket */ + ProtocolInfo.dwCatalogEntryId = Socket->SharedData.CatalogEntryId; + ProtocolInfo.dwServiceFlags1 = Socket->SharedData.ServiceFlags1; + ProtocolInfo.dwProviderFlags = Socket->SharedData.ProviderFlags; + AcceptSocket = WSPSocket (Socket->SharedData.AddressFamily, + Socket->SharedData.SocketType, + Socket->SharedData.Protocol, + &ProtocolInfo, + GroupID, + Socket->SharedData.CreateFlags, + NULL); + + /* Set up the Accept Structure */ + AcceptData.ListenHandle = AcceptSocket; + AcceptData.SequenceNumber = ListenReceiveData->SequenceNumber; + + /* Send IOCTL to Accept */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_ACCEPT, + &AcceptData, + sizeof(AcceptData), + NULL, + 0); + + /* Return Address in SOCKADDR FORMAT */ + RtlCopyMemory (SocketAddress, + &ListenReceiveData->Address.Address[0].AddressType, + sizeof(RemoteAddress)); + + /* Return Socket */ + return AcceptSocket; } - -INT -WSPAPI +int +WSPAPI WSPConnect( - IN SOCKET s, - IN CONST LPSOCKADDR name, - IN INT namelen, - IN LPWSABUF lpCallerData, - OUT LPWSABUF lpCalleeData, - IN LPQOS lpSQOS, - IN LPQOS lpGQOS, - OUT LPINT lpErrno) + SOCKET Handle, + struct sockaddr * SocketAddress, + int SocketAddressLength, + LPWSABUF lpCallerData, + LPWSABUF lpCalleeData, + LPQOS lpSQOS, + LPQOS lpGQOS, + LPINT lpErrno) { - FILE_REQUEST_CONNECT Request; - FILE_REPLY_CONNECT Reply; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; + IO_STATUS_BLOCK IOSB; + PAFD_CONNECT_INFO ConnectInfo; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + UCHAR ConnectBuffer[0x22]; + ULONG ConnectDataLength; + ULONG InConnectDataLength; + UINT BindAddressLength; + PSOCKADDR BindAddress; - AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s)); + AFD_DbgPrint(MID_TRACE,("Called\n")); - Request.name = name; - Request.namelen = namelen; - Request.lpCallerData = lpCallerData; - Request.lpCalleeData = lpCalleeData; - Request.lpSQOS = lpSQOS; - Request.lpGQOS = lpGQOS; + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - Status = NtDeviceIoControlFile( - (HANDLE)s, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_AFD_CONNECT, - &Request, - sizeof(FILE_REQUEST_CONNECT), - &Reply, - sizeof(FILE_REPLY_CONNECT)); - if (Status == STATUS_PENDING) { - AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n")); - /* FIXME: Wait only for blocking sockets */ - Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL); - } + /* Bind us First */ + if (Socket->SharedData.State == SocketOpen) { + + /* Get the Wildcard Address */ + BindAddressLength = Socket->HelperData->MaxWSAddressLength; + BindAddress = HeapAlloc(GetProcessHeap(), 0, BindAddressLength); + Socket->HelperData->WSHGetWildcardSockaddr (Socket->HelperContext, + BindAddress, + &BindAddressLength); - if (!NT_SUCCESS(Status)) { - *lpErrno = Reply.Status; - return INVALID_SOCKET; + /* Bind it */ + WSPBind(Handle, BindAddress, BindAddressLength, NULL); } - return 0; + /* Set the Connect Data */ + if (lpCallerData != NULL) { + ConnectDataLength = lpCallerData->len; + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_SET_CONNECT_DATA, + lpCallerData->buf, + ConnectDataLength, + NULL, + 0); + } + + /* Dynamic Structure...ugh */ + ConnectInfo = (PAFD_CONNECT_INFO)ConnectBuffer; + + /* Set up Address in TDI Format */ + ConnectInfo->RemoteAddress.TAAddressCount = 1; + ConnectInfo->RemoteAddress.Address[0].AddressLength = SocketAddressLength - sizeof(SocketAddress->sa_family); + RtlCopyMemory (&ConnectInfo->RemoteAddress.Address[0].AddressType, + SocketAddress, + SocketAddressLength); + + /* Tell AFD that we want Connection Data back, have it allocate a buffer */ + if (lpCalleeData != NULL) { + InConnectDataLength = lpCalleeData->len; + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_SET_CONNECT_DATA_SIZE, + &InConnectDataLength, + sizeof(InConnectDataLength), + NULL, + 0); + } + + /* AFD doesn't seem to care if these are invalid, but let's 0 them anyways */ + ConnectInfo->Root = 0; + ConnectInfo->UseSAN = FALSE; + ConnectInfo->Unknown = 0; + + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_CONNECT, + ConnectInfo, + 0x22, + NULL, + 0); + + /* Get any pending connect data */ + if (lpCalleeData != NULL) { + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_CONNECT_DATA, + NULL, + 0, + lpCalleeData->buf, + lpCalleeData->len); + } + + AFD_DbgPrint(MID_TRACE,("Ending\n")); + + return STATUS_SUCCESS; +} +int +WSPAPI +WSPShutdown( + SOCKET Handle, + int HowTo, + LPINT lpErrno) + +{ + IO_STATUS_BLOCK IOSB; + AFD_DISCONNECT_INFO DisconnectInfo; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + + AFD_DbgPrint(MID_TRACE,("Called\n")); + + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); + + /* Set AFD Disconnect Type */ + switch (HowTo) { + + case SD_RECEIVE: + DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV; + Socket->SharedData.ReceiveShutdown = TRUE; + break; + + case SD_SEND: + DisconnectInfo.DisconnectType= AFD_DISCONNECT_SEND; + Socket->SharedData.SendShutdown = TRUE; + break; + + case SD_BOTH: + DisconnectInfo.DisconnectType = AFD_DISCONNECT_RECV | AFD_DISCONNECT_SEND; + Socket->SharedData.ReceiveShutdown = TRUE; + Socket->SharedData.SendShutdown = TRUE; + break; + } + + DisconnectInfo.Timeout = RtlConvertLongToLargeInteger(-1); + + /* Send IOCTL */ + Status = NtDeviceIoControlFile((HANDLE)Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_DISCONNECT, + &DisconnectInfo, + sizeof(DisconnectInfo), + NULL, + 0); + + /* Wait for return */ + if (Status == STATUS_PENDING) { + WaitForSingleObject(SockEvent, 0); + } + + AFD_DbgPrint(MID_TRACE,("Ending\n")); + + return 0; } @@ -656,42 +907,6 @@ WSPGetSockName( IN OUT LPINT namelen, OUT LPINT lpErrno) { - FILE_REQUEST_GETNAME Request; - FILE_REPLY_GETNAME Reply; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; - - AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s)); - - Request.Peer = FALSE; - - Status = NtDeviceIoControlFile( - (HANDLE)s, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_AFD_GETNAME, - &Request, - sizeof(FILE_REQUEST_GETNAME), - &Reply, - sizeof(FILE_REPLY_GETNAME)); - 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 INVALID_SOCKET; - } - else - { - *namelen = min(*namelen, Reply.NameSize); - RtlCopyMemory(name, &Reply.Name, *namelen); - } - return 0; } @@ -704,138 +919,10 @@ WSPGetPeerName( IN OUT LPINT namelen, OUT LPINT lpErrno) { - FILE_REQUEST_GETNAME Request; - FILE_REPLY_GETNAME Reply; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; - - AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s)); - - Request.Peer = TRUE; - - Status = NtDeviceIoControlFile( - (HANDLE)s, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_AFD_GETNAME, - &Request, - sizeof(FILE_REQUEST_GETNAME), - &Reply, - sizeof(FILE_REPLY_GETNAME)); - 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 INVALID_SOCKET; - } - else - { - *namelen = min(*namelen, Reply.NameSize); - RtlCopyMemory(name, &Reply.Name, *namelen); - } - + return 0; } - -NTSTATUS OpenCommandChannel( - VOID) -/* - * FUNCTION: Opens a command channel to afd.sys - * ARGUMENTS: - * None - * 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, ("Called\n")); - - EaShort = sizeof(FILE_FULL_EA_INFORMATION) + - AFD_SOCKET_LENGTH + - sizeof(AFD_SOCKET_INFORMATION); - - EaLength = EaShort; - - 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 = TRUE; - - 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); - - if (!NT_SUCCESS(Status)) { - AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n", - (UINT)Status)); - return Status; - } - - CommandChannel = FileHandle; - - return STATUS_SUCCESS; -} - - -NTSTATUS CloseCommandChannel( - VOID) -/* - * FUNCTION: Closes command channel to afd.sys - * ARGUMENTS: - * None - * RETURNS: - * Status of operation - */ -{ - AFD_DbgPrint(MAX_TRACE, ("Called.\n")); - - return NtClose(CommandChannel); -} - - INT WSPAPI WSPStartup( @@ -856,49 +943,14 @@ WSPStartup( * Status of operation */ { - HMODULE hWS2_32; NTSTATUS Status; - INT Error; AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested)); Status = NO_ERROR; - EnterCriticalSection(&InitCriticalSection); - Upcalls = UpcallTable; - if (StartupCount == 0) { - /* First time called */ - - Status = OpenCommandChannel(); - if (NT_SUCCESS(Status)) { - hWS2_32 = GetModuleHandle(L"ws2_32.dll"); - if (hWS2_32 != NULL) { - lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST) - GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest"); - if (lpWPUCompleteOverlappedRequest != NULL) { - StartupCount++; - } else { - AFD_DbgPrint(MIN_TRACE, ("GetProcAddress() failed for WPUCompleteOverlappedRequest\n")); - CloseCommandChannel(); - Error = WSASYSNOTREADY; - } - } else { - AFD_DbgPrint(MIN_TRACE, ("GetModuleHandle() failed for ws2_32.dll\n")); - CloseCommandChannel(); - Error = WSASYSNOTREADY; - } - } else { - AFD_DbgPrint(MIN_TRACE, ("Cannot open afd.sys\n")); - Error = WSASYSNOTREADY; - } - } else { - StartupCount++; - } - - LeaveCriticalSection(&InitCriticalSection); - if (Status == NO_ERROR) { lpProcTable->lpWSPAccept = WSPAccept; lpProcTable->lpWSPAddressToString = WSPAddressToString; @@ -955,20 +1007,7 @@ WSPCleanup( { AFD_DbgPrint(MAX_TRACE, ("\n")); - EnterCriticalSection(&InitCriticalSection); - - if (StartupCount > 0) { - StartupCount--; - - if (StartupCount == 0) { - AFD_DbgPrint(MAX_TRACE, ("Cleaning up msafd.dll.\n")); - - CloseCommandChannel(); - } - } - - LeaveCriticalSection(&InitCriticalSection); - + AFD_DbgPrint(MAX_TRACE, ("Leaving.\n")); *lpErrno = NO_ERROR; @@ -977,27 +1016,162 @@ WSPCleanup( } + +int +GetSocketInformation( + PSOCKET_INFORMATION Socket, + ULONG AfdInformationClass, + PULONG Ulong OPTIONAL, + PLARGE_INTEGER LargeInteger OPTIONAL) +{ + IO_STATUS_BLOCK IOSB; + AFD_INFO InfoData; + NTSTATUS Status; + + /* Set Info Class */ + InfoData.InformationClass = AfdInformationClass; + + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_INFO, + &InfoData, + sizeof(InfoData), + &InfoData, + sizeof(InfoData)); + + /* Wait for return */ + if (Status == STATUS_PENDING) { + WaitForSingleObject(SockEvent, 0); + } + + /* Return Information */ + *Ulong = InfoData.Information.Ulong; + if (LargeInteger != NULL) { + *LargeInteger = InfoData.Information.LargeInteger; + } + + return 0; + +} + + +int +SetSocketInformation( + PSOCKET_INFORMATION Socket, + ULONG AfdInformationClass, + PULONG Ulong OPTIONAL, + PLARGE_INTEGER LargeInteger OPTIONAL) +{ + IO_STATUS_BLOCK IOSB; + AFD_INFO InfoData; + NTSTATUS Status; + + /* Set Info Class */ + InfoData.InformationClass = AfdInformationClass; + + /* Set Information */ + InfoData.Information.Ulong = *Ulong; + if (LargeInteger != NULL) { + InfoData.Information.LargeInteger = *LargeInteger; + } + + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_GET_INFO, + &InfoData, + sizeof(InfoData), + NULL, + 0); + + /* Wait for return */ + if (Status == STATUS_PENDING) { + WaitForSingleObject(SockEvent, 0); + } + + return 0; + +} + +PSOCKET_INFORMATION +GetSocketStructure( + SOCKET Handle) +{ + ULONG i; + + for (i=0; iHandle == Handle) { + return Sockets[i]; + } + } + return 0; +} + +int CreateContext(PSOCKET_INFORMATION Socket) +{ + IO_STATUS_BLOCK IOSB; + SOCKET_CONTEXT ContextData; + NTSTATUS Status; + + /* Create Context */ + ContextData.SharedData = Socket->SharedData; + ContextData.SizeOfHelperData = 0; + RtlCopyMemory (&ContextData.LocalAddress, + Socket->LocalAddress, + Socket->SharedData.SizeOfLocalAddress); + RtlCopyMemory (&ContextData.RemoteAddress, + Socket->RemoteAddress, + Socket->SharedData.SizeOfRemoteAddress); + + /* Send IOCTL */ + Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle, + SockEvent, + NULL, + NULL, + &IOSB, + IOCTL_AFD_SET_CONTEXT, + &ContextData, + sizeof(ContextData), + NULL, + 0); + + return 0; +} + BOOL STDCALL DllMain(HANDLE hInstDll, ULONG dwReason, PVOID Reserved) { - AFD_DbgPrint(MAX_TRACE, ("DllMain of msafd.dll\n")); - + switch (dwReason) { case DLL_PROCESS_ATTACH: + + AFD_DbgPrint(MAX_TRACE, ("Loading MSAFD.DLL \n")); + /* Don't need thread attach notifications so disable them to improve performance */ DisableThreadLibraryCalls(hInstDll); - InitializeCriticalSection(&InitCriticalSection); - - InitializeListHead(&MsAfdListenRequests); + /* List of DLL Helpers */ + InitializeListHead(&SockHelpersListHead); + /* Heap to use when allocating */ GlobalHeap = GetProcessHeap(); - CreateHelperDLLDatabase(); + /* Allocate Heap for 1024 Sockets, can be expanded later */ + Sockets = HeapAlloc(GetProcessHeap(), 0, sizeof(PSOCKET_INFORMATION) * 1024); + + AFD_DbgPrint(MAX_TRACE, ("MSAFD.DLL has been loaded\n")); + break; case DLL_THREAD_ATTACH: @@ -1007,11 +1181,6 @@ DllMain(HANDLE hInstDll, break; case DLL_PROCESS_DETACH: - - DestroyHelperDLLDatabase(); - - DeleteCriticalSection(&InitCriticalSection); - break; } @@ -1021,3 +1190,5 @@ DllMain(HANDLE hInstDll, } /* EOF */ + + diff --git a/reactos/lib/msafd/misc/event.c b/reactos/lib/msafd/misc/event.c index 910c6cfa490..5ad54353afa 100644 --- a/reactos/lib/msafd/misc/event.c +++ b/reactos/lib/msafd/misc/event.c @@ -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 -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; + IO_STATUS_BLOCK IOSB; + AFD_EVENT_SELECT_INFO EventSelectInfo; + PSOCKET_INFORMATION Socket = NULL; + NTSTATUS Status; + ULONG BlockMode; - Request.hEventObject = hEventObject; - Request.lNetworkEvents = lNetworkEvents; + /* Get the Socket Structure associate to this Socket*/ + Socket = GetSocketStructure(Handle); - 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); - } + /* Set Socket to Non-Blocking */ + BlockMode = 1; + SetSocketInformation(Socket, AFD_INFO_BLOCKING_MODE, &BlockMode, NULL); + Socket->SharedData.NonBlocking = TRUE; - if (!NT_SUCCESS(Status)) { - AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status)); - *lpErrno = WSAENOBUFS; - return SOCKET_ERROR; + /* 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; - *lpErrno = Reply.Status; + /* Set Events to wait for */ + if (lNetworkEvents & FD_READ) { + EventSelectInfo.Events |= AFD_EVENT_RECEIVE; + } - return 0; + 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); + } + + /* Set Socket Data*/ + Socket->EventObject = hEventObject; + Socket->NetworkEvents = lNetworkEvents; + + return 0; } + INT WSPAPI WSPEnumNetworkEvents( @@ -64,42 +109,7 @@ WSPEnumNetworkEvents( 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 */ diff --git a/reactos/lib/msafd/misc/helpers.c b/reactos/lib/msafd/misc/helpers.c index 3760e87712c..89d6d31d543 100644 --- a/reactos/lib/msafd/misc/helpers.c +++ b/reactos/lib/msafd/misc/helpers.c @@ -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 #include @@ -13,275 +15,503 @@ CRITICAL_SECTION HelperDLLDatabaseLock; LIST_ENTRY HelperDLLDatabaseListHead; -PWSHELPER_DLL CreateHelperDLL( - LPWSTR LibraryName) + +INT +SockGetTdiName( + PINT AddressFamily, + PINT SocketType, + PINT Protocol, + GROUP Group, + DWORD Flags, + PUNICODE_STRING TransportName, + PVOID *HelperDllContext, + PHELPER_DATA *HelperDllData, + PDWORD Events) { - PWSHELPER_DLL HelperDLL; + PHELPER_DATA HelperData; + PWSTR Transports; + PWSTR Transport; + PWINSOCK_MAPPING Mapping; + PLIST_ENTRY Helpers; + INT Status; - HelperDLL = HeapAlloc(GlobalHeap, 0, sizeof(WSHELPER_DLL)); - if (!HelperDLL) - return NULL; + AFD_DbgPrint(MID_TRACE,("Called\n")); - InitializeCriticalSection(&HelperDLL->Lock); - HelperDLL->hModule = NULL; - lstrcpyW(HelperDLL->LibraryName, LibraryName); - HelperDLL->Mapping = NULL; + /* Check in our Current Loaded Helpers */ + for (Helpers = SockHelpersListHead.Flink; + Helpers != &SockHelpersListHead; + Helpers = Helpers->Flink ) { - EnterCriticalSection(&HelperDLLDatabaseLock); - InsertTailList(&HelperDLLDatabaseListHead, &HelperDLL->ListEntry); - LeaveCriticalSection(&HelperDLLDatabaseLock); + HelperData = CONTAINING_RECORD(Helpers, HELPER_DATA, Helpers); - AFD_DbgPrint(MAX_TRACE, ("Returning helper at (0x%X).\n", HelperDLL)); + /* See if this Mapping works for us */ + if (SockIsTripleInMapping (HelperData->Mapping, + *AddressFamily, + *SocketType, + *Protocol)) { - return HelperDLL; -} + /* Call the Helper Dll function get the Transport Name */ + if (HelperData->WSHOpenSocket2 == NULL ) { - -INT DestroyHelperDLL( - PWSHELPER_DLL HelperDLL) -{ - INT Status; - - AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X).\n", HelperDLL)); - - EnterCriticalSection(&HelperDLLDatabaseLock); - RemoveEntryList(&HelperDLL->ListEntry); - LeaveCriticalSection(&HelperDLLDatabaseLock); - - if (HelperDLL->hModule) { - Status = UnloadHelperDLL(HelperDLL); - } else { - Status = NO_ERROR; - } - - if (HelperDLL->Mapping) - HeapFree(GlobalHeap, 0, HelperDLL->Mapping); - - DeleteCriticalSection(&HelperDLL->Lock); - - HeapFree(GlobalHeap, 0, HelperDLL); - - 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; + /* 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 + ); } + + /* Return the Helper Pointers */ + *HelperDllData = HelperData; + return NO_ERROR; } - - CurrentEntry = CurrentEntry->Flink; } - LeaveCriticalSection(&HelperDLLDatabaseLock); - AFD_DbgPrint(MAX_TRACE, ("Could not locate helper DLL.\n")); + /* Get the Transports available */ + Status = SockLoadTransportList(&Transports); - return NULL; -} - - -INT GetHelperDLLEntries( - PWSHELPER_DLL HelperDLL) -{ - PVOID e; + /* Check for error */ + if (Status) { + AFD_DbgPrint(MIN_TRACE, ("Can't get transport list\n")); + return Status; + } - /* The following functions MUST be supported */ - e = GetProcAddress(HelperDLL->hModule, "WSHEnumProtocols"); - if (!e) return ERROR_BAD_PROVIDER; - HelperDLL->EntryTable.lpWSHEnumProtocols = e; + /* Loop through each transport until we find one that can satisfy us */ + for (Transport = Transports; + *Transports != 0; + Transport += wcslen(Transport) + 1) { - 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; - - e = GetProcAddress(HelperDLL->hModule, "WSHGetProviderGuid"); - HelperDLL->EntryTable.lpWSHGetProviderGuid = e; - - e = GetProcAddress(HelperDLL->hModule, "WSHGetWSAProtocolInfo"); - HelperDLL->EntryTable.lpWSHGetWSAProtocolInfo = e; - - e = GetProcAddress(HelperDLL->hModule, "WSHIoctl"); - HelperDLL->EntryTable.lpWSHIoctl = e; - - e = GetProcAddress(HelperDLL->hModule, "WSHJoinLeaf"); - HelperDLL->EntryTable.lpWSHJoinLeaf = e; - - e = GetProcAddress(HelperDLL->hModule, "WSHOpenSocket2"); - HelperDLL->EntryTable.lpWSHOpenSocket2 = e; - - e = GetProcAddress(HelperDLL->hModule, "WSHStringToAddress"); - HelperDLL->EntryTable.lpWSHStringToAddress = e; - - return NO_ERROR; -} - - -INT LoadHelperDLL( - PWSHELPER_DLL HelperDLL) -{ - 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; -} - - -INT UnloadHelperDLL( - PWSHELPER_DLL HelperDLL) -{ - INT Status = NO_ERROR; - - AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X) hModule (0x%X).\n", HelperDLL, HelperDLL->hModule)); - - if (HelperDLL->hModule) { - if (!FreeLibrary(HelperDLL->hModule)) { - Status = GetLastError(); + /* 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; } - HelperDLL->hModule = NULL; - } - return Status; + /* See if this Mapping works for us */ + if (SockIsTripleInMapping(Mapping, *AddressFamily, *SocketType, *Protocol)) { + + /* 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; + } + + /* 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 + ); + } + + /* Return the Helper Pointers */ + *HelperDllData = HelperData; + HeapFree(GlobalHeap, 0, Transports); + HeapFree(GlobalHeap, 0, Mapping); + return NO_ERROR; + } + + HeapFree(GlobalHeap, 0, Mapping); + } + HeapFree(GlobalHeap, 0, Transports); + return WSAEINVAL; } - -VOID CreateHelperDLLDatabase(VOID) +INT +SockLoadTransportMapping( + PWSTR TransportName, + PWINSOCK_MAPPING *Mapping) { - PWSHELPER_DLL HelperDLL; + PWSTR TransportKey; + HKEY KeyHandle; + ULONG MappingSize; + LONG Status; - InitializeCriticalSection(&HelperDLLDatabaseLock); + AFD_DbgPrint(MID_TRACE,("Called: TransportName %ws\n", TransportName)); - InitializeListHead(&HelperDLLDatabaseListHead); + /* Allocate a Buffer */ + TransportKey = HeapAlloc(GlobalHeap, 0, (54 + wcslen(TransportName)) * sizeof(WCHAR)); - /* 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; - - HelperDLL->Mapping->Rows = 5; - HelperDLL->Mapping->Columns = 3; - - HelperDLL->Mapping->Mapping[0].AddressFamily = AF_INET; - HelperDLL->Mapping->Mapping[0].SocketType = SOCK_STREAM; - HelperDLL->Mapping->Mapping[0].Protocol = 0; - - HelperDLL->Mapping->Mapping[1].AddressFamily = AF_INET; - HelperDLL->Mapping->Mapping[1].SocketType = SOCK_STREAM; - HelperDLL->Mapping->Mapping[1].Protocol = IPPROTO_TCP; - - HelperDLL->Mapping->Mapping[2].AddressFamily = AF_INET; - HelperDLL->Mapping->Mapping[2].SocketType = SOCK_DGRAM; - HelperDLL->Mapping->Mapping[2].Protocol = 0; - - HelperDLL->Mapping->Mapping[3].AddressFamily = AF_INET; - HelperDLL->Mapping->Mapping[3].SocketType = SOCK_DGRAM; - HelperDLL->Mapping->Mapping[3].Protocol = IPPROTO_UDP; - - HelperDLL->Mapping->Mapping[4].AddressFamily = AF_INET; - HelperDLL->Mapping->Mapping[4].SocketType = SOCK_RAW; - HelperDLL->Mapping->Mapping[4].Protocol = 0; - - LoadHelperDLL(HelperDLL); -} - - -VOID DestroyHelperDLLDatabase(VOID) -{ - 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); - - CurrentEntry = NextEntry; + /* Check for error */ + if (TransportKey == NULL) { + AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); + return WSAEINVAL; } - DeleteCriticalSection(&HelperDLLDatabaseLock); + /* 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; + } + + /* Find out how much space we need for the Mapping */ + Status = RegQueryValueExW(KeyHandle, L"Mapping", NULL, NULL, NULL, &MappingSize); + + /* Check for error */ + if (Status) { + AFD_DbgPrint(MIN_TRACE, ("Error reading transport mapping registry\n")); + return WSAEINVAL; + } + + /* Allocate Memory for the Mapping */ + *Mapping = HeapAlloc(GlobalHeap, 0, MappingSize); + + /* Check for error */ + if (*Mapping == NULL) { + AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); + return WSAEINVAL; + } + + /* 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; + } + + /* Close key and return */ + RegCloseKey(KeyHandle); + return 0; +} + +INT +SockLoadTransportList( + PWSTR *TransportList) +{ + 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; + } + + /* Allocate Memory for the Transport List */ + *TransportList = HeapAlloc(GlobalHeap, 0, TransportListSize); + + /* Check for error */ + if (*TransportList == NULL) { + AFD_DbgPrint(MIN_TRACE, ("Buffer allocation failed\n")); + return WSAEINVAL; + } + + /* 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; + } + + /* Close key and return */ + RegCloseKey(KeyHandle); + return 0; +} + +INT +SockLoadHelperDll( + PWSTR TransportName, + PWINSOCK_MAPPING Mapping, + PHELPER_DATA *HelperDllData) +{ + 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)); + + /* 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; + } + + /* 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; + } + + 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; + } + + /* 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; + } + + /* 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; + } + + /* Close Key */ + RegCloseKey(KeyHandle); + + /* 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; +} + +BOOL +SockIsTripleInMapping( + PWINSOCK_MAPPING Mapping, + INT AddressFamily, + INT SocketType, + INT Protocol) +{ + /* 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)); + + /* 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; + } + } + AFD_DbgPrint(MID_TRACE,("Not found\n")); + return FALSE; } /* EOF */ diff --git a/reactos/lib/msafd/misc/sndrcv.c b/reactos/lib/msafd/misc/sndrcv.c index 7fd001ad1b8..bc68203343f 100644 --- a/reactos/lib/msafd/misc/sndrcv.c +++ b/reactos/lib/msafd/misc/sndrcv.c @@ -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 #include @@ -25,80 +27,489 @@ WSPAsyncSelect( } -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; + PIO_STATUS_BLOCK IOSB; + IO_STATUS_BLOCK DummyIOSB; + AFD_RECV_INFO RecvInfo; + NTSTATUS Status; + PVOID APCContext; + PVOID APCFunction; + HANDLE Event; - AFD_DbgPrint(MAX_TRACE, ("Called.\n")); + /* Set up the Receive Structure */ + RecvInfo.BufferArray = (PAFD_WSABUF)lpBuffers; + RecvInfo.BufferCount = dwBufferCount; + RecvInfo.TdiFlags = 0; + RecvInfo.AfdFlags = 0; - Size = dwBufferCount * sizeof(WSABUF); + /* 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; + } - 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; - } + if (*ReceiveFlags & MSG_PEEK) { + RecvInfo.TdiFlags |= TDI_RECEIVE_PEEK; + } - /* 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)); - - 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; + if (*ReceiveFlags & MSG_PARTIAL) { + RecvInfo.TdiFlags |= TDI_RECEIVE_NORMAL; + } } - AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n", - Reply.NumberOfBytesRecvd)); + /* Verifiy if we should use APC */ - *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd; - //*lpFlags = 0; + 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, + &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 +WSPRecvFrom( + 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) +{ + 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; + } + } + + /* 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; + 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 +WSPSend( + SOCKET Handle, + LPWSABUF lpBuffers, + DWORD dwBufferCount, + LPDWORD lpNumberOfBytesSent, + DWORD iFlags, + LPWSAOVERLAPPED lpOverlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, + LPWSATHREADID lpThreadId, + LPINT lpErrno) +{ + 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; + } + + if (Status == STATUS_PENDING) { + return WSA_IO_PENDING; + } + + /* Return Number of bytes Sent */ + *lpNumberOfBytesSent = (DWORD)IOSB->Information; + + /* 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 WSPRecvDisconnect( @@ -111,160 +522,6 @@ WSPRecvDisconnect( return 0; } -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) -{ - 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)); - - 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, ("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); - - return 0; -} - - -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) -{ - 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 - - /* 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; - } - - AFD_DbgPrint(MAX_TRACE, ("Send successful.\n")); - - return 0; -} INT @@ -279,78 +536,4 @@ WSPSendDisconnect( return 0; } - -INT -WSPAPI -WSPSendTo( - 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, - 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")); - - return 0; -} - /* EOF */ diff --git a/reactos/lib/msafd/misc/stubs.c b/reactos/lib/msafd/misc/stubs.c index 9f32e79e7f9..8aa4b57f97c 100644 --- a/reactos/lib/msafd/misc/stubs.c +++ b/reactos/lib/msafd/misc/stubs.c @@ -152,20 +152,6 @@ WSPSetSockOpt( return 0; } - -INT -WSPAPI -WSPShutdown( - IN SOCKET s, - IN INT how, - OUT LPINT lpErrno) -{ - UNIMPLEMENTED - - return 0; -} - - INT WSPAPI WSPStringToAddress( diff --git a/reactos/lib/msafd/msafd.def b/reactos/lib/msafd/msafd.def index 80ae18c2a43..eb61b1a5830 100644 --- a/reactos/lib/msafd/msafd.def +++ b/reactos/lib/msafd/msafd.def @@ -3,6 +3,6 @@ LIBRARY msafd.dll EXPORTS -WSPStartup@76 +WSPStartup=_WSPStartup@76 ; EOF