mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
First commit of afd and msafd onto head.
tcpip: Turned off debug info in CVS. svn path=/trunk/; revision=10210
This commit is contained in:
parent
cd35daab59
commit
0f1eb55991
32 changed files with 4654 additions and 4259 deletions
|
@ -1,219 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/afd.c
|
||||
* PURPOSE: MSAFD kernel mode module
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
#include <rosrtl/string.h>
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
/* See debug.h for debug/trace constants */
|
||||
//DWORD DebugTraceLevel = MID_TRACE;
|
||||
DWORD DebugTraceLevel = DEBUG_ULTRA;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
NPAGED_LOOKASIDE_LIST BufferLookasideList;
|
||||
NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
|
||||
NPAGED_LOOKASIDE_LIST ListenRequestLookasideList;
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
AfdFileSystemControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
AfdDispatch(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: IOCTL dispatch routine
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to a device object for this driver
|
||||
* Irp = Pointer to a I/O request packet
|
||||
* RETURNS:
|
||||
* Status of the operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
BOOL DoComplete = TRUE;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X), IrpSp->FileObject (0x%X).\n",
|
||||
DeviceObject, Irp, IrpSp->FileObject));
|
||||
|
||||
Irp->IoStatus.Information = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
|
||||
case IOCTL_AFD_BIND:
|
||||
Status = AfdDispBind(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_LISTEN:
|
||||
Status = AfdDispListen(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_SENDTO:
|
||||
Status = AfdDispSendTo(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_RECVFROM:
|
||||
Status = AfdDispRecvFrom(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_SELECT:
|
||||
Status = AfdDispSelect(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_EVENTSELECT:
|
||||
Status = AfdDispEventSelect(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_ENUMNETWORKEVENTS:
|
||||
Status = AfdDispEnumNetworkEvents(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_RECV:
|
||||
Status = AfdDispRecv(Irp, IrpSp);
|
||||
DoComplete = FALSE;
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_SEND:
|
||||
Status = AfdDispSend(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_CONNECT:
|
||||
Status = AfdDispConnect(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_GETNAME:
|
||||
Status = AfdDispGetName(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
default:
|
||||
Irp->IoStatus.Information = 0;
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%X).\n",
|
||||
IrpSp->Parameters.DeviceIoControl.IoControlCode));
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING && DoComplete) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL AfdUnload(
|
||||
PDRIVER_OBJECT DriverObject)
|
||||
/*
|
||||
* FUNCTION: Unloads the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = Pointer to driver object created by the system
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
DriverEntry(
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Called by the system to initialize the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\Afd");
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_NAMED_PIPE,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Could not create device (0x%X).\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
DeviceObject->Flags |= DO_DIRECT_IO;
|
||||
|
||||
DeviceExt = DeviceObject->DeviceExtension;
|
||||
KeInitializeSpinLock(&DeviceExt->FCBListLock);
|
||||
InitializeListHead(&DeviceExt->FCBListHead);
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = AfdRead;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AfdFileSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AfdClose;
|
||||
|
||||
DriverObject->DriverUnload = AfdUnload;
|
||||
|
||||
/* ExInitializeNPagedLookasideList(
|
||||
&BufferLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(AFD_BUFFER),
|
||||
TAG('A', 'F', 'D', 'B'),
|
||||
0);*/
|
||||
|
||||
/* ExInitializeNPagedLookasideList(
|
||||
&ReadRequestLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(AFD_READ_REQUEST),
|
||||
TAG('A', 'F', 'D', 'R'),
|
||||
0);*/
|
||||
|
||||
ExInitializeNPagedLookasideList(
|
||||
&ListenRequestLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(AFD_LISTEN_REQUEST),
|
||||
TAG('A', 'F', 'D', 'L'),
|
||||
0);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
87
reactos/drivers/net/afd/afd/bind.c
Normal file
87
reactos/drivers/net/afd/afd/bind.c
Normal file
|
@ -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 );
|
||||
}
|
||||
|
201
reactos/drivers/net/afd/afd/connect.c
Normal file
201
reactos/drivers/net/afd/afd/connect.c
Normal file
|
@ -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 );
|
||||
}
|
68
reactos/drivers/net/afd/afd/context.c
Normal file
68
reactos/drivers/net/afd/afd/context.c
Normal file
|
@ -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 );
|
||||
}
|
File diff suppressed because it is too large
Load diff
52
reactos/drivers/net/afd/afd/info.c
Normal file
52
reactos/drivers/net/afd/afd/info.c
Normal file
|
@ -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 );
|
||||
}
|
61
reactos/drivers/net/afd/afd/listen.c
Normal file
61
reactos/drivers/net/afd/afd/listen.c
Normal file
|
@ -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 );
|
||||
}
|
212
reactos/drivers/net/afd/afd/lock.c
Normal file
212
reactos/drivers/net/afd/afd/lock.c
Normal file
|
@ -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 );
|
||||
}
|
||||
|
344
reactos/drivers/net/afd/afd/main.c
Normal file
344
reactos/drivers/net/afd/afd/main.c
Normal file
|
@ -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 */
|
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/opnclose.c
|
||||
* PURPOSE: File object creation and destruction
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
PAFDFCB AfdInitializeFCB(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_OBJECT FileObject OPTIONAL)
|
||||
/*
|
||||
* FUNCTION: Allocates and initializes a File Control Block structure
|
||||
*/
|
||||
{
|
||||
PAFDFCB NewFCB;
|
||||
|
||||
NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
|
||||
if (!NewFCB)
|
||||
return NULL;
|
||||
|
||||
RtlZeroMemory(NewFCB, sizeof(AFDFCB));
|
||||
|
||||
ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource);
|
||||
ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource);
|
||||
|
||||
NewFCB->DeviceExt = DeviceExt;
|
||||
NewFCB->ReferenceCount = 1;
|
||||
NewFCB->OpenHandleCount = 1;
|
||||
|
||||
NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
|
||||
NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
InitializeListHead(&NewFCB->CCBListHead);
|
||||
|
||||
InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
|
||||
|
||||
InitializeListHead(&NewFCB->ReceiveQueue);
|
||||
KeInitializeSpinLock(&NewFCB->ReceiveQueueLock);
|
||||
|
||||
InitializeListHead(&NewFCB->ReadRequestQueue);
|
||||
|
||||
InitializeListHead(&NewFCB->ListenRequestQueue);
|
||||
|
||||
if (FileObject)
|
||||
FileObject->FsContext = (PVOID)NewFCB;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
|
||||
|
||||
return NewFCB;
|
||||
}
|
||||
|
||||
|
||||
PAFDCCB AfdInitializeCCB(
|
||||
PAFDFCB FCB,
|
||||
PFILE_OBJECT FileObject)
|
||||
/*
|
||||
* FUNCTION: Allocates and initializes a Context Control Block structure
|
||||
*/
|
||||
{
|
||||
PAFDCCB NewCCB;
|
||||
|
||||
NewCCB = ExAllocatePool(NonPagedPool, sizeof(AFDCCB));
|
||||
if (!NewCCB)
|
||||
return NULL;
|
||||
|
||||
RtlZeroMemory(NewCCB, sizeof(AFDCCB));
|
||||
|
||||
NewCCB->FileObject = FileObject;
|
||||
|
||||
FileObject->FsContext2 = (PVOID)NewCCB;
|
||||
|
||||
InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("CCB created for file object (0x%X) at (0x%X).\n", FileObject, NewCCB));
|
||||
|
||||
return NewCCB;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
AfdCreate(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PAFD_SOCKET_INFORMATION SocketInfo;
|
||||
PFILE_FULL_EA_INFORMATION EaInfo;
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
NTSTATUS Status;
|
||||
ULONG EaLength;
|
||||
PAFDFCB FCB;
|
||||
PAFDCCB CCB;
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
assert(DeviceObject);
|
||||
|
||||
DeviceExt = DeviceObject->DeviceExtension;
|
||||
|
||||
EaInfo = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* Parameter check */
|
||||
if (!EaInfo) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + EaInfo->EaNameLength);
|
||||
|
||||
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
|
||||
EaInfo->EaNameLength +
|
||||
EaInfo->EaValueLength;
|
||||
|
||||
if (EaLength < sizeof(FILE_FULL_EA_INFORMATION) +
|
||||
AFD_SOCKET_LENGTH + sizeof(AFD_SOCKET_INFORMATION)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("EA information has invalid length.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) length is (%d).\n", EaInfo, EaLength));
|
||||
|
||||
/* FIXME: File/socket could already be open, do a search for it */
|
||||
|
||||
FCB = AfdInitializeFCB(DeviceExt, FileObject);
|
||||
|
||||
CCB = AfdInitializeCCB(FCB, FileObject);
|
||||
|
||||
if (CCB && FCB) {
|
||||
FCB->CommandChannel = SocketInfo->CommandChannel;
|
||||
|
||||
if (!FCB->CommandChannel) {
|
||||
FCB->AddressFamily = SocketInfo->AddressFamily;
|
||||
FCB->SocketType = SocketInfo->SocketType;
|
||||
FCB->Protocol = SocketInfo->Protocol;
|
||||
FCB->SocketName = SocketInfo->Name;
|
||||
FCB->HelperContext = SocketInfo->HelperContext;
|
||||
FCB->NotificationEvents = SocketInfo->NotificationEvents;
|
||||
|
||||
FCB->TdiDeviceName.Length = 0;
|
||||
FCB->TdiDeviceName.MaximumLength = SocketInfo->TdiDeviceName.MaximumLength;
|
||||
FCB->TdiDeviceName.Buffer = ExAllocatePool(
|
||||
NonPagedPool,
|
||||
FCB->TdiDeviceName.MaximumLength);
|
||||
|
||||
if (FCB->TdiDeviceName.Buffer) {
|
||||
RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
|
||||
|
||||
/* Open address file now for raw sockets */
|
||||
if (FCB->SocketType == SOCK_RAW) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
|
||||
|
||||
Status = TdiOpenAddressFile(
|
||||
&FCB->TdiDeviceName,
|
||||
&SocketInfo->Name,
|
||||
&FCB->TdiAddressObjectHandle,
|
||||
&FCB->TdiAddressObject);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
Status = AfdRegisterEventHandlers(FCB);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
FCB->State = SOCKET_STATE_BOUND;
|
||||
} else {
|
||||
AFD_DbgPrint(MAX_TRACE, ("AfdRegisterEventHandlers() failed (0x%X).\n", Status));
|
||||
}
|
||||
} else {
|
||||
AFD_DbgPrint(MAX_TRACE, ("TdiOpenAddressFile() failed (0x%X).\n", Status));
|
||||
}
|
||||
} else
|
||||
Status = STATUS_SUCCESS;
|
||||
} else
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
} else
|
||||
Status = STATUS_SUCCESS;
|
||||
} else
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
/* FIXME: Cleanup */
|
||||
AFD_DbgPrint(MAX_TRACE, ("FIXME: Cleanup.\n"));
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
AfdKillListenRequests(PAFDFCB FCB)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unimplemented.\n"));
|
||||
|
||||
/*ExFreeToNPagedLookasideList(&ListenRequestLookasideList,
|
||||
(PVOID)ListenRequest);*/
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
AfdClose(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
NTSTATUS Status;
|
||||
PAFDFCB FCB;
|
||||
PAFDCCB CCB;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
assert(DeviceObject);
|
||||
assert(FileObject);
|
||||
|
||||
FCB = FileObject->FsContext;
|
||||
CCB = FileObject->FsContext2;
|
||||
|
||||
switch (IrpSp->MajorFunction) {
|
||||
/* Close a file object */
|
||||
case IRP_MJ_CLOSE:
|
||||
FCB->ReferenceCount--;
|
||||
if (FCB->ReferenceCount < 1) {
|
||||
if (!FCB->CommandChannel) {
|
||||
/* Kill outstanding listen requests */
|
||||
AfdKillListenRequests(FCB);
|
||||
|
||||
/* Close TDI connection file object */
|
||||
if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
|
||||
TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
|
||||
FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* Close TDI address file object */
|
||||
if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
|
||||
AfdDeregisterEventHandlers(FCB);
|
||||
TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
|
||||
FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(FCB);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
/* Release resources bound to a file object */
|
||||
case IRP_MJ_CLEANUP:
|
||||
FCB->OpenHandleCount--;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
ExFreePool(CCB);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
||||
// ExFreePool(CCB);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", Irp));
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/rdwr.c
|
||||
* PURPOSE: File object read/write functions
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
NTSTATUS AfdReadFile(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_OBJECT FileObject,
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
ULONG Offset)
|
||||
/*
|
||||
* FUNCTION: Reads data from a file
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
AfdRead(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
#if 1
|
||||
UNIMPLEMENTED
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
#else
|
||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION IoSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IoSp->FileObject;
|
||||
NTSTATUS Status;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG Offset;
|
||||
|
||||
Length = IoSp->Parameters.Read.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = IoSp->Parameters.Read.ByteOffset.u.LowPart;
|
||||
|
||||
Status = AfdReadFile(DeviceExt, FileObject, Buffer, Length, Offset);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
AfdWrite(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IoSp->FileObject;
|
||||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG Offset;
|
||||
PAFDFCB FCB;
|
||||
PAFDCCB CCB;
|
||||
|
||||
FCB = FileObject->FsContext;
|
||||
CCB = FileObject->FsContext2;
|
||||
|
||||
assert(FCB);
|
||||
assert(CCB);
|
||||
|
||||
Length = IoSp->Parameters.Write.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = IoSp->Parameters.Write.ByteOffset.u.LowPart;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called. Length (%d) Buffer (0x%X) Offset (0x%X)\n",
|
||||
Length, Buffer, Offset));
|
||||
|
||||
assert((FCB->SocketType == SOCK_STREAM) || (FCB->SocketType == SOCK_DGRAM));
|
||||
|
||||
switch (FCB->SocketType) {
|
||||
case SOCK_STREAM:
|
||||
/* FIXME: Support connectionful communication */
|
||||
break;
|
||||
case SOCK_DGRAM:
|
||||
/* Connectionless communication */
|
||||
//Status = TdiSendDatagram(FCB->TdiAddressObject, WH2N(2000), 0x7F000001, Buffer, Length);
|
||||
//if (!NT_SUCCESS(Status)) {
|
||||
Length = 0;
|
||||
//}
|
||||
break;
|
||||
case SOCK_RAW:
|
||||
/* FIXME: Support raw communication */
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
338
reactos/drivers/net/afd/afd/read.c
Normal file
338
reactos/drivers/net/afd/afd/read.c
Normal file
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -1,316 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/routines.c
|
||||
* PURPOSE: Support routines
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/02-2001 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
#include <debug.h>
|
||||
|
||||
#ifndef DONT_USE_ME_THIS_WAY_IM_LIFTED_FROM_NTOSKRNL_XXX_DO_THIS_THE_RIGHT_WAY
|
||||
LONG FASTCALL
|
||||
XxInterlockedExchange(PLONG Target,
|
||||
LONG Value);
|
||||
|
||||
__asm__("\n\t.global @XxInterlockedExchange@8\n\t"
|
||||
"@XxInterlockedExchange@8:\n\t"
|
||||
"xchgl %edx,(%ecx)\n\t"
|
||||
"movl %edx,%eax\n\t"
|
||||
"ret\n\t");
|
||||
|
||||
#define InterlockedExchange XxInterlockedExchange
|
||||
#endif
|
||||
|
||||
VOID DumpName(
|
||||
LPSOCKADDR Name)
|
||||
{
|
||||
AFD_DbgPrint(MIN_TRACE, ("DumpName:\n"));
|
||||
AFD_DbgPrint(MIN_TRACE, (" sa_family: %d\n", Name->sa_family));
|
||||
AFD_DbgPrint(MIN_TRACE, (" sin_port: %d\n", WN2H(((LPSOCKADDR_IN)Name)->sin_port)));
|
||||
AFD_DbgPrint(MIN_TRACE, (" in_addr: 0x%x\n", WN2H(((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr)));
|
||||
}
|
||||
|
||||
|
||||
ULONG WSABufferSize(
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount)
|
||||
{
|
||||
ULONG i;
|
||||
LPWSABUF p;
|
||||
ULONG Count = 0;
|
||||
|
||||
p = Buffers;
|
||||
for (i = 0; i < BufferCount; i++) {
|
||||
Count += p->len;
|
||||
p++;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS MergeWSABuffers(
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount,
|
||||
PVOID Destination,
|
||||
ULONG MaxLength,
|
||||
PULONG BytesCopied)
|
||||
{
|
||||
ULONG Length;
|
||||
LPWSABUF p;
|
||||
ULONG i;
|
||||
|
||||
*BytesCopied = 0;
|
||||
if (BufferCount == 0)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
p = Buffers;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
|
||||
AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
|
||||
|
||||
for (i = 0; i < BufferCount; i++) {
|
||||
Length = p->len;
|
||||
if (Length > MaxLength)
|
||||
/* Don't copy out of bounds */
|
||||
Length = MaxLength;
|
||||
|
||||
RtlCopyMemory(Destination, p->buf, Length);
|
||||
Destination += Length;
|
||||
AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
|
||||
p++;
|
||||
AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
|
||||
|
||||
*BytesCopied += Length;
|
||||
|
||||
MaxLength -= Length;
|
||||
if (MaxLength == 0)
|
||||
/* Destination buffer is full */
|
||||
break;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID TryToSatisfyRecvRequest( PAFDFCB FCB, BOOL Continuous ) {
|
||||
PAFD_READ_REQUEST ReadRequest;
|
||||
PLIST_ENTRY Entry;
|
||||
NTSTATUS Status;
|
||||
ULONG Count = 0;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
|
||||
|
||||
while (!IsListEmpty(&FCB->ReadRequestQueue) &&
|
||||
!IsListEmpty(&FCB->ReceiveQueue)) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
|
||||
|
||||
Entry = RemoveHeadList(&FCB->ReadRequestQueue);
|
||||
ReadRequest = CONTAINING_RECORD(Entry, AFD_READ_REQUEST, ListEntry);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE,("ReadRequest: (li) %x %x %x\n",
|
||||
ReadRequest->Irp,
|
||||
ReadRequest->RecvFromRequest,
|
||||
ReadRequest->RecvFromReply));
|
||||
|
||||
Status = FillWSABuffers(
|
||||
FCB,
|
||||
ReadRequest->RecvFromRequest->Buffers,
|
||||
ReadRequest->RecvFromRequest->BufferCount,
|
||||
&Count,
|
||||
Continuous );
|
||||
|
||||
ReadRequest->RecvFromReply->NumberOfBytesRecvd = Count;
|
||||
ReadRequest->RecvFromReply->Status = NO_ERROR;
|
||||
|
||||
ReadRequest->Irp->IoStatus.Information =
|
||||
sizeof(*ReadRequest->RecvFromReply);
|
||||
ReadRequest->Irp->IoStatus.Status = Status;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", ReadRequest->Irp));
|
||||
|
||||
IoSetCancelRoutine(ReadRequest->Irp, NULL);
|
||||
IoCompleteRequest(ReadRequest->Irp, IO_NETWORK_INCREMENT);
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Bytes received (0x%X).\n", Count));
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTES: ReceiveQueueLock must be acquired for the FCB when called
|
||||
*/
|
||||
NTSTATUS FillWSABuffers(
|
||||
PAFDFCB FCB,
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount,
|
||||
PULONG BytesCopied,
|
||||
BOOL Continuous)
|
||||
{
|
||||
PUCHAR DstData, SrcData;
|
||||
UINT DstSize, SrcSize;
|
||||
UINT Count, Total;
|
||||
PAFD_BUFFER SrcBuffer;
|
||||
PMDL Mdl;
|
||||
PLIST_ENTRY Entry;
|
||||
|
||||
*BytesCopied = 0;
|
||||
if (BufferCount == 0)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
if (IsListEmpty(&FCB->ReceiveQueue))
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Entry = RemoveHeadList(&FCB->ReceiveQueue);
|
||||
SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
|
||||
SrcData = SrcBuffer->Buffer.buf + SrcBuffer->Offset;
|
||||
SrcSize = SrcBuffer->Buffer.len - SrcBuffer->Offset;
|
||||
|
||||
/* First buffer: map the pages so we can access them */
|
||||
Mdl = (PMDL)Buffers->buf;
|
||||
DstData = MmMapLockedPages( Mdl, KernelMode );
|
||||
DstSize = Buffers->len;
|
||||
|
||||
/* Copy the data */
|
||||
for (Total = 0;;) {
|
||||
/* Find out how many bytes we can copy at one time */
|
||||
if (DstSize < SrcSize)
|
||||
Count = DstSize;
|
||||
else
|
||||
Count = SrcSize;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcData (0x%X) Count (0x%X).\n",
|
||||
DstData, SrcData, Count));
|
||||
|
||||
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
|
||||
|
||||
Total += Count;
|
||||
|
||||
SrcSize -= Count;
|
||||
if (SrcSize == 0) {
|
||||
ExFreePool(SrcBuffer->Buffer.buf);
|
||||
ExFreePool(SrcBuffer);
|
||||
|
||||
/* No more bytes in source buffer. Proceed to the next buffer
|
||||
in the source buffer chain if there is one */
|
||||
if (IsListEmpty(&FCB->ReceiveQueue)) {
|
||||
SrcBuffer = NULL;
|
||||
SrcData = 0;
|
||||
SrcSize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Entry = RemoveHeadList(&FCB->ReceiveQueue);
|
||||
SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
|
||||
SrcData = SrcBuffer->Buffer.buf;
|
||||
SrcSize = SrcBuffer->Buffer.len;
|
||||
}
|
||||
|
||||
DstSize -= Count;
|
||||
if (DstSize == 0) {
|
||||
/* No more bytes in destination buffer. Proceed to
|
||||
the next buffer in the destination buffer chain */
|
||||
BufferCount--;
|
||||
if (BufferCount < 1)
|
||||
break;
|
||||
|
||||
/* And cleanup the pages. */
|
||||
MmUnmapLockedPages( DstData, Mdl );
|
||||
MmUnlockPages( Mdl );
|
||||
IoFreeMdl( Mdl );
|
||||
|
||||
Buffers++;
|
||||
Mdl = (PMDL)Buffers->buf;
|
||||
DstData = MmMapLockedPages( Mdl, KernelMode );
|
||||
DstSize = Buffers->len;
|
||||
}
|
||||
}
|
||||
|
||||
if (SrcSize > 0) {
|
||||
SrcBuffer->Offset += Total;
|
||||
InsertHeadList(&FCB->ReceiveQueue, Entry);
|
||||
} else if (SrcBuffer != NULL) {
|
||||
ExFreePool(SrcBuffer->Buffer.buf);
|
||||
ExFreePool(SrcBuffer);
|
||||
}
|
||||
|
||||
*BytesCopied = Total;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG ChecksumCompute(
|
||||
PVOID Data,
|
||||
UINT Count,
|
||||
ULONG Seed)
|
||||
/*
|
||||
* FUNCTION: Calculate checksum of a buffer
|
||||
* ARGUMENTS:
|
||||
* Data = Pointer to buffer with data
|
||||
* Count = Number of bytes in buffer
|
||||
* Seed = Previously calculated checksum (if any)
|
||||
* RETURNS:
|
||||
* Checksum of buffer
|
||||
*/
|
||||
{
|
||||
/* FIXME: This should be done in assembler */
|
||||
|
||||
register ULONG Sum = Seed;
|
||||
|
||||
while (Count > 1) {
|
||||
Sum += *(PUSHORT)Data;
|
||||
Count -= 2;
|
||||
Data = (PVOID) ((ULONG_PTR) Data + 2);
|
||||
}
|
||||
|
||||
/* Add left-over byte, if any */
|
||||
if (Count > 0)
|
||||
Sum += *(PUCHAR)Data;
|
||||
|
||||
/* Fold 32-bit sum to 16 bits */
|
||||
while (Sum >> 16)
|
||||
Sum = (Sum & 0xFFFF) + (Sum >> 16);
|
||||
|
||||
return ~Sum;
|
||||
}
|
||||
|
||||
VOID BuildIPv4Header(
|
||||
PIPv4_HEADER IPHeader,
|
||||
ULONG TotalSize,
|
||||
ULONG Protocol,
|
||||
PSOCKADDR SourceAddress,
|
||||
PSOCKADDR DestinationAddress)
|
||||
{
|
||||
PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
|
||||
PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
|
||||
|
||||
/* Version = 4, Length = 5 DWORDs */
|
||||
IPHeader->VerIHL = 0x45;
|
||||
/* Normal Type-of-Service */
|
||||
IPHeader->Tos = 0;
|
||||
/* Length of header and data */
|
||||
IPHeader->TotalLength = WH2N((USHORT)TotalSize);
|
||||
/* Identification */
|
||||
IPHeader->Id = 0;
|
||||
/* One fragment at offset 0 */
|
||||
IPHeader->FlagsFragOfs = 0;
|
||||
/* Time-to-Live is 128 */
|
||||
IPHeader->Ttl = 128;
|
||||
/* Protocol number */
|
||||
IPHeader->Protocol = Protocol;
|
||||
/* Checksum is 0 (calculated later) */
|
||||
IPHeader->Checksum = 0;
|
||||
/* Source address */
|
||||
IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
|
||||
/* Destination address */
|
||||
IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
|
||||
|
||||
/* Calculate checksum of IP header */
|
||||
IPHeader->Checksum = (USHORT)
|
||||
ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
|
||||
}
|
||||
|
||||
/* EOF */
|
237
reactos/drivers/net/afd/afd/select.c
Normal file
237
reactos/drivers/net/afd/afd/select.c
Normal file
|
@ -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"));
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
#include "debug.h"
|
||||
#include "tdiconn.h"
|
||||
|
||||
#ifdef DBG
|
||||
|
@ -57,10 +58,12 @@ NTSTATUS 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;
|
||||
}
|
||||
|
|
|
@ -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 <afd.h>
|
||||
#include "debug.h"
|
||||
#include "tdiconn.h"
|
||||
|
||||
DWORD TdiAddressSizeFromType(
|
||||
ULONG Type)
|
||||
/*
|
||||
* FUNCTION: Returns the size of a TDI style address of given address type
|
||||
* ARGUMENTS:
|
||||
* Type = TDI style address type
|
||||
* RETURNS:
|
||||
* Size of TDI style address, 0 if Type is not valid
|
||||
*/
|
||||
{
|
||||
switch (Type) {
|
||||
case TDI_ADDRESS_TYPE_IP:
|
||||
return sizeof(TA_IP_ADDRESS);
|
||||
/* FIXME: More to come */
|
||||
}
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unknown TDI address type (%d).\n", Type));
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
|
269
reactos/drivers/net/afd/afd/write.c
Normal file
269
reactos/drivers/net/afd/afd/write.c
Normal file
|
@ -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 );
|
||||
}
|
||||
|
47
reactos/drivers/net/afd/doc/simple_select.txt
Normal file
47
reactos/drivers/net/afd/doc/simple_select.txt
Normal file
|
@ -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
|
||||
|
|
@ -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 <ntddk.h>
|
||||
#include <tdi.h>
|
||||
#include <tdikrnl.h>
|
||||
#include <tdiinfo.h>
|
||||
#include <string.h>
|
||||
#include <ndis.h>
|
||||
#include <shared.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <rosrtl/string.h>
|
||||
#include <winsock2.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntifs.h>
|
||||
#include <ddk/tdiinfo.h>
|
||||
#include <ddk/tdikrnl.h>
|
||||
#include <afd/shared.h>
|
||||
#include <debug.h>
|
||||
#include <ddk/tdi.h>
|
||||
#include <ddk/ndis.h>
|
||||
#include <tcpmisc.h>
|
||||
#include <tcpioctl.h>
|
||||
#else
|
||||
#include <ntdef.h>
|
||||
#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*/
|
||||
|
|
17
reactos/drivers/net/afd/include/tdi_proto.h
Normal file
17
reactos/drivers/net/afd/include/tdi_proto.h
Normal file
|
@ -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*/
|
|
@ -2,27 +2,30 @@
|
|||
#define _TDICONN_H
|
||||
|
||||
#include <afd.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <ntddtdi.h>
|
||||
#endif
|
||||
|
||||
typedef VOID *PTDI_CONNECTION_INFO_PAIR;
|
||||
|
||||
DWORD TdiAddressSizeFromType( ULONG Type );
|
||||
DWORD TdiAddressSizeFromName( LPSOCKADDR Name );
|
||||
VOID TdiBuildAddressIPv4( PTA_IP_ADDRESS Address,
|
||||
LPSOCKADDR Name );
|
||||
NTSTATUS TdiBuildAddress( PTA_ADDRESS Address,
|
||||
LPSOCKADDR Name );
|
||||
NTSTATUS TdiBuildName( LPSOCKADDR Name,
|
||||
PTA_ADDRESS Address );
|
||||
PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress );
|
||||
UINT TaLengthOfAddress( PTA_ADDRESS Addr );
|
||||
UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr );
|
||||
VOID TaCopyAddressInPlace( PTA_ADDRESS Target, PTA_ADDRESS Source );
|
||||
VOID TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target,
|
||||
PTRANSPORT_ADDRESS Source );
|
||||
UINT TdiAddressSizeFromType( UINT Type );
|
||||
UINT TdiAddressSizeFromName( PTRANSPORT_ADDRESS Name );
|
||||
NTSTATUS TdiBuildConnectionInfoInPlace
|
||||
( PTDI_CONNECTION_INFORMATION ConnInfo, LPSOCKADDR Name );
|
||||
( PTDI_CONNECTION_INFORMATION ConnInfo, PTA_ADDRESS Name );
|
||||
NTSTATUS TdiBuildConnectionInfo
|
||||
( PTDI_CONNECTION_INFORMATION *ConnectionInfo, LPSOCKADDR Name );
|
||||
( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTA_ADDRESS Name );
|
||||
NTSTATUS TdiBuildNullConnectionInfoToPlace
|
||||
( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type );
|
||||
NTSTATUS TdiBuildNullConnectionInfo
|
||||
( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type );
|
||||
NTSTATUS TdiBuildConnectionInfoPair
|
||||
( PTDI_CONNECTION_INFO_PAIR ConnectionInfo, LPSOCKADDR From, LPSOCKADDR To );
|
||||
( PTDI_CONNECTION_INFO_PAIR ConnectionInfo, PTA_ADDRESS From, PTA_ADDRESS To );
|
||||
PTA_ADDRESS TdiGetRemoteAddress( PTDI_CONNECTION_INFORMATION TdiConn );
|
||||
|
||||
#endif/*_TDICONN_H*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <info.h>
|
||||
#include <memtrack.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
|
||||
#ifndef NDEBUG
|
||||
DWORD DebugTraceLevel = 0x7fffffff;
|
||||
|
|
|
@ -9,53 +9,64 @@
|
|||
|
||||
#include <msafd.h>
|
||||
|
||||
typedef struct _WSHELPER_DLL_ENTRIES {
|
||||
PWSH_ADDRESS_TO_STRING lpWSHAddressToString;
|
||||
PWSH_ENUM_PROTOCOLS lpWSHEnumProtocols;
|
||||
PWSH_GET_BROADCAST_SOCKADDR lpWSHGetBroadcastSockaddr;
|
||||
PWSH_GET_PROVIDER_GUID lpWSHGetProviderGuid;
|
||||
PWSH_GET_SOCKADDR_TYPE lpWSHGetSockaddrType;
|
||||
PWSH_GET_SOCKET_INFORMATION lpWSHGetSocketInformation;
|
||||
PWSH_GET_WILDCARD_SOCKEADDR lpWSHGetWildcardSockaddr;
|
||||
PWSH_GET_WINSOCK_MAPPING lpWSHGetWinsockMapping;
|
||||
PWSH_GET_WSAPROTOCOL_INFO lpWSHGetWSAProtocolInfo;
|
||||
PWSH_IOCTL lpWSHIoctl;
|
||||
PWSH_JOIN_LEAF lpWSHJoinLeaf;
|
||||
PWSH_NOTIFY lpWSHNotify;
|
||||
PWSH_OPEN_SOCKET lpWSHOpenSocket;
|
||||
PWSH_OPEN_SOCKET2 lpWSHOpenSocket2;
|
||||
PWSH_SET_SOCKET_INFORMATION lpWSHSetSocketInformation;
|
||||
PWSH_STRING_TO_ADDRESS lpWSHStringToAddress;
|
||||
} WSHELPER_DLL_ENTRIES, *PWSHELPER_DLL_ENTRIES;
|
||||
typedef struct _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 */
|
||||
|
||||
|
|
|
@ -11,23 +11,102 @@
|
|||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntifs.h>
|
||||
#include <wsahelp.h>
|
||||
#include <wsahelp.h> /* comment for msvc */
|
||||
//#include "C:\Programming\ReactOS\reactos\w32api\include\wsahelp.h" uncomment for MSVC
|
||||
#include <winsock2.h>
|
||||
#include <ws2spi.h>
|
||||
#include <ddk/tdi.h>
|
||||
//#include "C:\Programming\ReactOS\reactos\w32api\include\ddk\tdi.h" uncomment for MSVC
|
||||
#include <ddk/tdi.h> /* comment for msvc */
|
||||
#include <afd/shared.h>
|
||||
#include <helpers.h>
|
||||
#include <debug.h>
|
||||
|
||||
/*typedef _MSAFD_LISTEN_REQUEST
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
HANDLE Socket;
|
||||
} MSAFD_LISTEN_REQUEST, *PMSAFD_LISTEN_REQUEST;*/
|
||||
|
||||
|
||||
extern HANDLE GlobalHeap;
|
||||
extern WSPUPCALLTABLE Upcalls;
|
||||
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
|
||||
extern LIST_ENTRY SockHelpersListHead;
|
||||
extern HANDLE SockEvent;
|
||||
|
||||
typedef enum _SOCKET_STATE {
|
||||
SocketOpen,
|
||||
SocketBound,
|
||||
SocketBoundUdp,
|
||||
SocketConnected,
|
||||
SocketClosed
|
||||
} SOCKET_STATE, *PSOCKET_STATE;
|
||||
|
||||
typedef struct _SOCK_SHARED_INFO {
|
||||
SOCKET_STATE State;
|
||||
INT AddressFamily;
|
||||
INT SocketType;
|
||||
INT Protocol;
|
||||
INT SizeOfLocalAddress;
|
||||
INT SizeOfRemoteAddress;
|
||||
ULONG LingerData;
|
||||
ULONG SendTimeout;
|
||||
ULONG RecvTimeout;
|
||||
ULONG SizeOfRecvBuffer;
|
||||
ULONG SizeOfSendBuffer;
|
||||
struct {
|
||||
BOOLEAN Listening:1;
|
||||
BOOLEAN Broadcast:1;
|
||||
BOOLEAN Debug:1;
|
||||
BOOLEAN OobInline:1;
|
||||
BOOLEAN ReuseAddresses:1;
|
||||
BOOLEAN ExclusiveAddressUse:1;
|
||||
BOOLEAN NonBlocking:1;
|
||||
BOOLEAN DontUseWildcard:1;
|
||||
BOOLEAN ReceiveShutdown:1;
|
||||
BOOLEAN SendShutdown:1;
|
||||
BOOLEAN UseDelayedAcceptance:1;
|
||||
BOOLEAN UseSAN:1;
|
||||
}; // Flags
|
||||
DWORD CreateFlags;
|
||||
DWORD CatalogEntryId;
|
||||
DWORD ServiceFlags1;
|
||||
DWORD ProviderFlags;
|
||||
GROUP GroupID;
|
||||
DWORD GroupType;
|
||||
INT GroupPriority;
|
||||
INT SocketLastError;
|
||||
HWND hWnd;
|
||||
LONG Unknown;
|
||||
DWORD SequenceNumber;
|
||||
UINT wMsg;
|
||||
LONG Event;
|
||||
LONG DisabledEvents;
|
||||
} SOCK_SHARED_INFO, *PSOCK_SHARED_INFO;
|
||||
|
||||
typedef struct _SOCKET_INFORMATION {
|
||||
ULONG RefCount;
|
||||
SOCKET Handle;
|
||||
SOCK_SHARED_INFO SharedData;
|
||||
DWORD HelperEvents;
|
||||
PHELPER_DATA HelperData;
|
||||
PVOID HelperContext;
|
||||
PSOCKADDR LocalAddress;
|
||||
PSOCKADDR RemoteAddress;
|
||||
HANDLE TdiAddressHandle;
|
||||
HANDLE TdiConnectionHandle;
|
||||
PVOID AsyncData;
|
||||
HANDLE EventObject;
|
||||
LONG NetworkEvents;
|
||||
CRITICAL_SECTION Lock;
|
||||
PVOID SanData;
|
||||
BOOL TrySAN;
|
||||
SOCKADDR WSLocalAddress;
|
||||
SOCKADDR WSRemoteAddress;
|
||||
} SOCKET_INFORMATION, *PSOCKET_INFORMATION;
|
||||
|
||||
|
||||
typedef struct _SOCKET_CONTEXT {
|
||||
SOCK_SHARED_INFO SharedData;
|
||||
ULONG SizeOfHelperData;
|
||||
ULONG Padding;
|
||||
SOCKADDR LocalAddress;
|
||||
SOCKADDR RemoteAddress;
|
||||
/* Plus Helper Data */
|
||||
} SOCKET_CONTEXT, *PSOCKET_CONTEXT;
|
||||
|
||||
SOCKET
|
||||
WSPAPI
|
||||
|
@ -314,6 +393,28 @@ 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 */
|
||||
|
|
|
@ -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 \
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,58 +4,103 @@
|
|||
* FILE: misc/event.c
|
||||
* PURPOSE: Event handling
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Alex Ionescu (alex@relsoft.net)
|
||||
* REVISIONS:
|
||||
* CSH 15/06-2001 Created
|
||||
* Alex 16/07/2004 - Complete Rewrite
|
||||
*/
|
||||
|
||||
#include <msafd.h>
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
int
|
||||
WSPAPI
|
||||
WSPEventSelect(
|
||||
IN SOCKET s,
|
||||
IN WSAEVENT hEventObject,
|
||||
IN LONG lNetworkEvents,
|
||||
OUT LPINT lpErrno)
|
||||
SOCKET Handle,
|
||||
WSAEVENT hEventObject,
|
||||
long lNetworkEvents,
|
||||
LPINT lpErrno)
|
||||
{
|
||||
FILE_REQUEST_EVENTSELECT Request;
|
||||
FILE_REPLY_EVENTSELECT Reply;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
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 */
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
* FILE: misc/helpers.c
|
||||
* PURPOSE: Helper DLL management
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Alex Ionescu (alex@relsoft.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
* Alex 16/07/2004 - Complete Rewrite
|
||||
*/
|
||||
#include <msafd.h>
|
||||
#include <helpers.h>
|
||||
|
@ -13,275 +15,503 @@
|
|||
CRITICAL_SECTION HelperDLLDatabaseLock;
|
||||
LIST_ENTRY HelperDLLDatabaseListHead;
|
||||
|
||||
PWSHELPER_DLL CreateHelperDLL(
|
||||
LPWSTR LibraryName)
|
||||
|
||||
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 */
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
* FILE: misc/sndrcv.c
|
||||
* PURPOSE: Send/receive routines
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Alex Ionescu (alex@relsoft.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
* Alex 16/07/2004 - Complete Rewrite
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <msafd.h>
|
||||
|
@ -25,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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
LIBRARY msafd.dll
|
||||
|
||||
EXPORTS
|
||||
WSPStartup@76
|
||||
WSPStartup=_WSPStartup@76
|
||||
|
||||
; EOF
|
||||
|
|
Loading…
Reference in a new issue