mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 23:25:45 +00:00
[AFD, FORMATTING]
- get rid of unused OskitDumpBuffer - make the code in AFD better conform to ROS coding guidelines - fix some MSVC compilation errors (still not fully compiling with MSVC yet) [IP] - Add a sanity check in the TCPAcceptEventHandler svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52398
This commit is contained in:
parent
8e61bd7196
commit
7ba87c3d72
12 changed files with 1375 additions and 1036 deletions
|
@ -13,19 +13,19 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
NTSTATUS WarmSocketForBind( PAFD_FCB FCB )
|
NTSTATUS WarmSocketForBind(PAFD_FCB FCB)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n",
|
AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n",
|
||||||
FCB->LocalAddress->Address[0].AddressType));
|
FCB->LocalAddress->Address[0].AddressType));
|
||||||
|
|
||||||
if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer )
|
if (!FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Null Device\n"));
|
AFD_DbgPrint(MID_TRACE,("Null Device\n"));
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
if( !FCB->LocalAddress )
|
if (!FCB->LocalAddress)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("No local address\n"));
|
AFD_DbgPrint(MID_TRACE,("No local address\n"));
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -55,33 +55,35 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB )
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_BIND_DATA BindReq;
|
PAFD_BIND_DATA BindReq;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
DbgPrint("[AFD, AfdBindSocket] Called\n");
|
DbgPrint("[AFD, AfdBindSocket] Called\n");
|
||||||
|
|
||||||
if ( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return LostSocket( Irp );
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if ( !(BindReq = LockRequest( Irp, IrpSp )) )
|
if (!(BindReq = (PAFD_BIND_DATA)LockRequest(Irp, IrpSp)) )
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
||||||
|
|
||||||
if ( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
|
if (FCB->LocalAddress )
|
||||||
FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
|
ExFreePool(FCB->LocalAddress);
|
||||||
|
FCB->LocalAddress = TaCopyTransportAddress(&BindReq->Address);
|
||||||
|
|
||||||
if (FCB->LocalAddress)
|
if (FCB->LocalAddress)
|
||||||
Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
|
Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
|
||||||
FCB->LocalAddress );
|
FCB->LocalAddress );
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = WarmSocketForBind( FCB );
|
Status = WarmSocketForBind(FCB);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
|
AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
|
||||||
|
|
||||||
|
@ -116,4 +118,3 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
/* MSAFD relies on us returning the address file handle in the IOSB */
|
/* MSAFD relies on us returning the address file handle in the IOSB */
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, (ULONG_PTR)FCB->AddressFile.Handle );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, (ULONG_PTR)FCB->AddressFile.Handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,15 +12,17 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (FCB->ConnectOptionsSize == 0)
|
if (FCB->ConnectOptionsSize == 0)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
|
@ -42,11 +44,12 @@ AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PVOID ConnectOptions = LockRequest(Irp, IrpSp);
|
PVOID ConnectOptions = LockRequest(Irp, IrpSp);
|
||||||
UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!ConnectOptions)
|
if (!ConnectOptions)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -60,7 +63,8 @@ AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->ConnectOptions = ExAllocatePool(PagedPool, ConnectOptionsSize);
|
FCB->ConnectOptions = ExAllocatePool(PagedPool, ConnectOptionsSize);
|
||||||
if (!FCB->ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
if (!FCB->ConnectOptions)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
RtlCopyMemory(FCB->ConnectOptions,
|
RtlCopyMemory(FCB->ConnectOptions,
|
||||||
ConnectOptions,
|
ConnectOptions,
|
||||||
|
@ -77,11 +81,12 @@ AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp);
|
PUINT ConnectOptionsSize = (PUINT)LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!ConnectOptionsSize)
|
if (!ConnectOptionsSize)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -97,29 +102,33 @@ AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->ConnectOptions = ExAllocatePool(PagedPool, *ConnectOptionsSize);
|
FCB->ConnectOptions = ExAllocatePool(PagedPool, *ConnectOptionsSize);
|
||||||
if (!FCB->ConnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
if (!FCB->ConnectOptions)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
FCB->ConnectOptionsSize = *ConnectOptionsSize;
|
FCB->ConnectOptionsSize = *ConnectOptionsSize;
|
||||||
|
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (FCB->ConnectDataSize == 0)
|
if (FCB->ConnectDataSize == 0)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
|
|
||||||
ASSERT(FCB->ConnectData);
|
ASSERT(FCB->ConnectData);
|
||||||
|
|
||||||
if (FCB->FilledConnectData < BufferSize) BufferSize = FCB->FilledConnectData;
|
if (FCB->FilledConnectData < BufferSize)
|
||||||
|
BufferSize = FCB->FilledConnectData;
|
||||||
|
|
||||||
RtlCopyMemory(Irp->UserBuffer,
|
RtlCopyMemory(Irp->UserBuffer,
|
||||||
FCB->ConnectData,
|
FCB->ConnectData,
|
||||||
|
@ -134,11 +143,12 @@ AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PVOID ConnectData = LockRequest(Irp, IrpSp);
|
PVOID ConnectData = LockRequest(Irp, IrpSp);
|
||||||
UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!ConnectData)
|
if (!ConnectData)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -152,11 +162,10 @@ AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->ConnectData = ExAllocatePool(PagedPool, ConnectDataSize);
|
FCB->ConnectData = ExAllocatePool(PagedPool, ConnectDataSize);
|
||||||
if (!FCB->ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
if (!FCB->ConnectData)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
RtlCopyMemory(FCB->ConnectData,
|
RtlCopyMemory(FCB->ConnectData, ConnectData, ConnectDataSize);
|
||||||
ConnectData,
|
|
||||||
ConnectDataSize);
|
|
||||||
|
|
||||||
FCB->ConnectDataSize = ConnectDataSize;
|
FCB->ConnectDataSize = ConnectDataSize;
|
||||||
|
|
||||||
|
@ -169,11 +178,12 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PUINT ConnectDataSize = LockRequest(Irp, IrpSp);
|
PUINT ConnectDataSize = (PUINT)LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!ConnectDataSize)
|
if (!ConnectDataSize)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -189,7 +199,8 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->ConnectData = ExAllocatePool(PagedPool, *ConnectDataSize);
|
FCB->ConnectData = ExAllocatePool(PagedPool, *ConnectDataSize);
|
||||||
if (!FCB->ConnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
if (!FCB->ConnectData)
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
FCB->ConnectDataSize = *ConnectDataSize;
|
FCB->ConnectDataSize = *ConnectDataSize;
|
||||||
|
|
||||||
|
@ -201,7 +212,7 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB )
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer )
|
if (!FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Null Device\n"));
|
AFD_DbgPrint(MID_TRACE,("Null Device\n"));
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
@ -211,7 +222,7 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB )
|
||||||
&FCB->Connection.Handle,
|
&FCB->Connection.Handle,
|
||||||
&FCB->Connection.Object );
|
&FCB->Connection.Object );
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) )
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = TdiAssociateAddressFile( FCB->AddressFile.Handle,
|
Status = TdiAssociateAddressFile( FCB->AddressFile.Handle,
|
||||||
FCB->Connection.Object );
|
FCB->Connection.Object );
|
||||||
|
@ -235,18 +246,18 @@ NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB )
|
||||||
FCB->Recv.Size = FCB->Send.Size;
|
FCB->Recv.Size = FCB->Send.Size;
|
||||||
|
|
||||||
/* Allocate the receive area and start receiving */
|
/* Allocate the receive area and start receiving */
|
||||||
FCB->Recv.Window =
|
FCB->Recv.Window = ExAllocatePool(PagedPool, FCB->Recv.Size);
|
||||||
ExAllocatePool( PagedPool, FCB->Recv.Size );
|
|
||||||
|
|
||||||
if( !FCB->Recv.Window ) return STATUS_NO_MEMORY;
|
if (!FCB->Recv.Window)
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
FCB->Send.Window =
|
FCB->Send.Window = ExAllocatePool(PagedPool, FCB->Send.Size);
|
||||||
ExAllocatePool( PagedPool, FCB->Send.Size );
|
|
||||||
|
|
||||||
if( !FCB->Send.Window ) {
|
if (!FCB->Send.Window)
|
||||||
ExFreePool( FCB->Recv.Window );
|
{
|
||||||
FCB->Recv.Window = NULL;
|
ExFreePool( FCB->Recv.Window );
|
||||||
return STATUS_NO_MEMORY;
|
FCB->Recv.Window = NULL;
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->State = SOCKET_STATE_CONNECTED;
|
FCB->State = SOCKET_STATE_CONNECTED;
|
||||||
|
@ -260,7 +271,8 @@ NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB )
|
||||||
ReceiveComplete,
|
ReceiveComplete,
|
||||||
FCB );
|
FCB );
|
||||||
|
|
||||||
if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
|
if (Status == STATUS_PENDING)
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND;
|
FCB->PollState |= AFD_EVENT_CONNECT | AFD_EVENT_SEND;
|
||||||
FCB->PollStatus[FD_CONNECT_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_CONNECT_BIT] = STATUS_SUCCESS;
|
||||||
|
@ -270,10 +282,14 @@ NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB )
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI StreamSocketConnectComplete
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
StreamSocketConnectComplete
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
PVOID Context ) {
|
PVOID Context )
|
||||||
|
{
|
||||||
NTSTATUS Status = Irp->IoStatus.Status;
|
NTSTATUS Status = Irp->IoStatus.Status;
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PLIST_ENTRY NextIrpEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
|
@ -286,7 +302,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
|
|
||||||
/* I was wrong about this before as we can have pending writes to a not
|
/* I was wrong about this before as we can have pending writes to a not
|
||||||
* yet connected socket */
|
* yet connected socket */
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n",
|
AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n",
|
||||||
|
@ -295,10 +311,10 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
ASSERT(FCB->ConnectIrp.InFlightRequest == Irp);
|
ASSERT(FCB->ConnectIrp.InFlightRequest == Irp);
|
||||||
FCB->ConnectIrp.InFlightRequest = NULL;
|
FCB->ConnectIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED )
|
if (FCB->State == SOCKET_STATE_CLOSED)
|
||||||
{
|
{
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) )
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT]))
|
||||||
{
|
{
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
@ -306,16 +322,17 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Information = 0;
|
||||||
|
|
||||||
if( NextIrp->MdlAddress )
|
if( NextIrp->MdlAddress )
|
||||||
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation(NextIrp));
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
|
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
SocketStateUnlock( FCB );
|
|
||||||
|
SocketStateUnlock( FCB );
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !NT_SUCCESS(Irp->IoStatus.Status) )
|
if (!NT_SUCCESS(Irp->IoStatus.Status))
|
||||||
{
|
{
|
||||||
FCB->PollState |= AFD_EVENT_CONNECT_FAIL;
|
FCB->PollState |= AFD_EVENT_CONNECT_FAIL;
|
||||||
FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status;
|
FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status;
|
||||||
|
@ -327,7 +344,7 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Succeed pending irps on the FUNCTION_CONNECT list */
|
/* Succeed pending irps on the FUNCTION_CONNECT list */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) )
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT]))
|
||||||
{
|
{
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
@ -336,23 +353,27 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x\n", NextIrp);
|
DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x\n", NextIrp);
|
||||||
|
|
||||||
NextIrp->IoStatus.Status = Status;
|
NextIrp->IoStatus.Status = Status;
|
||||||
NextIrp->IoStatus.Information = NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0;
|
NextIrp->IoStatus.Information = (NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0);
|
||||||
|
|
||||||
if( NextIrp->MdlAddress )
|
if (NextIrp->MdlAddress)
|
||||||
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation(NextIrp));
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
|
IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if (NT_SUCCESS(Status))
|
||||||
Status = MakeSocketIntoConnection( FCB );
|
{
|
||||||
|
Status = MakeSocketIntoConnection(FCB);
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) ) {
|
if (!NT_SUCCESS(Status))
|
||||||
SocketStateUnlock( FCB );
|
{
|
||||||
return Status;
|
SocketStateUnlock(FCB);
|
||||||
}
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength, FCB->ConnectDataSize);
|
FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength,
|
||||||
|
FCB->ConnectDataSize);
|
||||||
if (FCB->FilledConnectData)
|
if (FCB->FilledConnectData)
|
||||||
{
|
{
|
||||||
RtlCopyMemory(FCB->ConnectData,
|
RtlCopyMemory(FCB->ConnectData,
|
||||||
|
@ -360,31 +381,33 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
FCB->FilledConnectData);
|
FCB->FilledConnectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength, FCB->ConnectOptionsSize);
|
FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength,
|
||||||
|
FCB->ConnectOptionsSize);
|
||||||
if (FCB->FilledConnectOptions)
|
if (FCB->FilledConnectOptions)
|
||||||
{
|
{
|
||||||
RtlCopyMemory(FCB->ConnectOptions,
|
RtlCopyMemory(FCB->ConnectOptions,
|
||||||
FCB->ConnectInfo->Options,
|
FCB->ConnectInfo->Options,
|
||||||
FCB->FilledConnectOptions);
|
FCB->FilledConnectOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
if (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND]))
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
{
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP,
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
Tail.Overlay.ListEntry);
|
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 )
|
AFD_DbgPrint(MID_TRACE,("Launching send request %x\n", NextIrp));
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
|
Status = AfdConnectedSocketWriteData(DeviceObject,
|
||||||
|
NextIrp,
|
||||||
|
IoGetCurrentIrpStackLocation( NextIrp ),
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock(FCB);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||||
|
|
||||||
|
@ -393,21 +416,23 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
|
||||||
|
|
||||||
/* Return the socket object for ths request only if it is a connected or
|
/* Return the socket object for ths request only if it is a connected or
|
||||||
stream type. */
|
stream type. */
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_CONNECT_INFO ConnectReq;
|
PAFD_CONNECT_INFO ConnectReq;
|
||||||
PTDI_CONNECTION_INFORMATION TargetAddress;
|
PTDI_CONNECTION_INFORMATION TargetAddress;
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
if( !(ConnectReq = LockRequest( Irp, IrpSp )) )
|
return LostSocket( Irp );
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
|
|
||||||
0 );
|
if (!(ConnectReq = LockRequest(Irp, IrpSp)))
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Connect request:\n"));
|
AFD_DbgPrint(MID_TRACE,("Connect request:\n"));
|
||||||
DbgPrint("[AFD, AfdStreamSocketConnect] Connect request:\n");
|
DbgPrint("[AFD, AfdStreamSocketConnect] Connect request:\n");
|
||||||
|
@ -417,12 +442,14 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
IrpSp->Parameters.DeviceIoControl.InputBufferLength );
|
IrpSp->Parameters.DeviceIoControl.InputBufferLength );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
|
if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
|
||||||
{
|
{
|
||||||
if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
|
if (FCB->RemoteAddress)
|
||||||
FCB->RemoteAddress = TaCopyTransportAddress( &ConnectReq->RemoteAddress );
|
ExFreePool(FCB->RemoteAddress);
|
||||||
|
|
||||||
|
FCB->RemoteAddress = TaCopyTransportAddress( &ConnectReq->RemoteAddress );
|
||||||
|
|
||||||
if( !FCB->RemoteAddress )
|
if (!FCB->RemoteAddress)
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
else
|
else
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
@ -430,7 +457,7 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( FCB->State )
|
switch (FCB->State)
|
||||||
{
|
{
|
||||||
case SOCKET_STATE_CONNECTED:
|
case SOCKET_STATE_CONNECTED:
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
@ -440,18 +467,18 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
|
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
|
||||||
|
|
||||||
case SOCKET_STATE_CREATED:
|
case SOCKET_STATE_CREATED:
|
||||||
if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
|
if (FCB->LocalAddress) ExFreePool(FCB->LocalAddress);
|
||||||
FCB->LocalAddress = TaBuildNullTransportAddress(
|
FCB->LocalAddress = TaBuildNullTransportAddress(
|
||||||
ConnectReq->RemoteAddress.Address[0].AddressType);
|
ConnectReq->RemoteAddress.Address[0].AddressType);
|
||||||
|
|
||||||
if( FCB->LocalAddress )
|
if (FCB->LocalAddress)
|
||||||
{
|
{
|
||||||
Status = WarmSocketForBind( FCB );
|
Status = WarmSocketForBind(FCB);
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) )
|
if (NT_SUCCESS(Status))
|
||||||
FCB->State = SOCKET_STATE_BOUND;
|
FCB->State = SOCKET_STATE_BOUND;
|
||||||
else
|
else
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
||||||
|
@ -459,29 +486,29 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
/* Drop through to SOCKET_STATE_BOUND */
|
/* Drop through to SOCKET_STATE_BOUND */
|
||||||
|
|
||||||
case SOCKET_STATE_BOUND:
|
case SOCKET_STATE_BOUND:
|
||||||
if( FCB->RemoteAddress )
|
if (FCB->RemoteAddress)
|
||||||
ExFreePool( FCB->RemoteAddress );
|
ExFreePool(FCB->RemoteAddress);
|
||||||
|
|
||||||
FCB->RemoteAddress = TaCopyTransportAddress( &ConnectReq->RemoteAddress );
|
FCB->RemoteAddress = TaCopyTransportAddress( &ConnectReq->RemoteAddress );
|
||||||
|
|
||||||
if( !FCB->RemoteAddress )
|
if (!FCB->RemoteAddress)
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = WarmSocketForConnection( FCB );
|
Status = WarmSocketForConnection(FCB);
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if (!NT_SUCCESS(Status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, &ConnectReq->RemoteAddress);
|
Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, &ConnectReq->RemoteAddress);
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) )
|
if (NT_SUCCESS(Status))
|
||||||
Status = TdiBuildConnectionInfo(&TargetAddress, &ConnectReq->RemoteAddress);
|
Status = TdiBuildConnectionInfo(&TargetAddress, &ConnectReq->RemoteAddress);
|
||||||
else break;
|
else break;
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) )
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
TargetAddress->UserData = FCB->ConnectData;
|
TargetAddress->UserData = FCB->ConnectData;
|
||||||
TargetAddress->UserDataLength = FCB->ConnectDataSize;
|
TargetAddress->UserDataLength = FCB->ConnectDataSize;
|
||||||
|
@ -503,8 +530,8 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
if( Status == STATUS_PENDING )
|
if( Status == STATUS_PENDING )
|
||||||
{
|
{
|
||||||
FCB->State = SOCKET_STATE_CONNECTING;
|
FCB->State = SOCKET_STATE_CONNECTING;
|
||||||
return LeaveIrpUntilLater(FCB, Irp, FUNCTION_CONNECT);
|
return LeaveIrpUntilLater(FCB, Irp, FUNCTION_CONNECT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -12,23 +12,25 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdGetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdGetContext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
UINT ContextSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
UINT ContextSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if( FCB->ContextSize < ContextSize ) ContextSize = FCB->ContextSize;
|
if (FCB->ContextSize < ContextSize)
|
||||||
|
ContextSize = FCB->ContextSize;
|
||||||
|
|
||||||
if( FCB->Context ) {
|
if (FCB->Context)
|
||||||
RtlCopyMemory( Irp->UserBuffer,
|
{
|
||||||
FCB->Context,
|
RtlCopyMemory( Irp->UserBuffer, FCB->Context, ContextSize );
|
||||||
ContextSize );
|
Status = STATUS_SUCCESS;
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||||
|
@ -36,14 +38,16 @@ AfdGetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, ContextSize );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, ContextSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp )
|
PIO_STACK_LOCATION IrpSp )
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, sizeof(ULONG));
|
return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, sizeof(ULONG));
|
||||||
|
@ -55,27 +59,31 @@ AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG));
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, sizeof(ULONG));
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdSetContext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PVOID Context = LockRequest(Irp, IrpSp);
|
PVOID Context = LockRequest(Irp, IrpSp);
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if (!Context)
|
if (!Context)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if( FCB->Context ) {
|
if (FCB->Context)
|
||||||
ExFreePool( FCB->Context );
|
{
|
||||||
FCB->ContextSize = 0;
|
ExFreePool( FCB->Context );
|
||||||
|
FCB->ContextSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FCB->Context = ExAllocatePool( PagedPool,
|
FCB->Context = ExAllocatePool( PagedPool,
|
||||||
IrpSp->Parameters.DeviceIoControl.InputBufferLength );
|
IrpSp->Parameters.DeviceIoControl.InputBufferLength );
|
||||||
|
|
||||||
if( !FCB->Context ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
if ( !FCB->Context )
|
||||||
|
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
||||||
|
|
||||||
FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
FCB->ContextSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
|
|
|
@ -13,125 +13,141 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "pseh/pseh2.h"
|
#include "pseh/pseh2.h"
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdGetInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
|
PAFD_INFO InfoReq = (PAFD_INFO)LockRequest(Irp, IrpSp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq,
|
AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq,
|
||||||
InfoReq ? InfoReq->InformationClass : 0));
|
InfoReq ? InfoReq->InformationClass : 0));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if (!InfoReq)
|
if (!InfoReq)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
_SEH2_TRY {
|
_SEH2_TRY
|
||||||
switch( InfoReq->InformationClass ) {
|
{
|
||||||
case AFD_INFO_RECEIVE_WINDOW_SIZE:
|
switch( InfoReq->InformationClass )
|
||||||
InfoReq->Information.Ulong = FCB->Recv.Size;
|
{
|
||||||
break;
|
case AFD_INFO_RECEIVE_WINDOW_SIZE:
|
||||||
|
InfoReq->Information.Ulong = FCB->Recv.Size;
|
||||||
|
break;
|
||||||
|
|
||||||
case AFD_INFO_SEND_WINDOW_SIZE:
|
case AFD_INFO_SEND_WINDOW_SIZE:
|
||||||
InfoReq->Information.Ulong = FCB->Send.Size;
|
InfoReq->Information.Ulong = FCB->Send.Size;
|
||||||
AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size));
|
AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AFD_INFO_GROUP_ID_TYPE:
|
case AFD_INFO_GROUP_ID_TYPE:
|
||||||
InfoReq->Information.LargeInteger.u.HighPart = FCB->GroupType;
|
InfoReq->Information.LargeInteger.u.HighPart = FCB->GroupType;
|
||||||
InfoReq->Information.LargeInteger.u.LowPart = FCB->GroupID;
|
InfoReq->Information.LargeInteger.u.LowPart = FCB->GroupID;
|
||||||
AFD_DbgPrint(MID_TRACE, ("Group ID: %d Group Type: %d\n", FCB->GroupID, FCB->GroupType));
|
AFD_DbgPrint(MID_TRACE, ("Group ID: %d Group Type: %d\n", FCB->GroupID, FCB->GroupType));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AFD_INFO_BLOCKING_MODE:
|
case AFD_INFO_BLOCKING_MODE:
|
||||||
InfoReq->Information.Ulong = FCB->BlockingMode;
|
InfoReq->Information.Ulong = FCB->BlockingMode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AFD_INFO_RECEIVE_CONTENT_SIZE:
|
case AFD_INFO_RECEIVE_CONTENT_SIZE:
|
||||||
/* Only touch InfoReq if a socket has been set up.
|
/* Only touch InfoReq if a socket has been set up.
|
||||||
Behaviour was verified under WinXP SP2. */
|
Behaviour was verified under WinXP SP2. */
|
||||||
if(FCB->AddressFile.Object)
|
if(FCB->AddressFile.Object)
|
||||||
InfoReq->Information.Ulong = FCB->Recv.Content - FCB->Recv.BytesUsed;
|
InfoReq->Information.Ulong = FCB->Recv.Content - FCB->Recv.BytesUsed;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AFD_INFO_SENDS_IN_PROGRESS:
|
case AFD_INFO_SENDS_IN_PROGRESS:
|
||||||
InfoReq->Information.Ulong = 0;
|
InfoReq->Information.Ulong = 0;
|
||||||
|
|
||||||
/* Count the queued sends */
|
/* Count the queued sends */
|
||||||
CurrentEntry = FCB->PendingIrpList[FUNCTION_SEND].Flink;
|
CurrentEntry = FCB->PendingIrpList[FUNCTION_SEND].Flink;
|
||||||
while (CurrentEntry != &FCB->PendingIrpList[FUNCTION_SEND])
|
while (CurrentEntry != &FCB->PendingIrpList[FUNCTION_SEND])
|
||||||
{
|
{
|
||||||
InfoReq->Information.Ulong++;
|
InfoReq->Information.Ulong++;
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
break;
|
default:
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
|
||||||
default:
|
InfoReq->InformationClass));
|
||||||
AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
InfoReq->InformationClass));
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n"));
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
break;
|
}
|
||||||
}
|
_SEH2_END;
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n"));
|
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
|
||||||
} _SEH2_END;
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||||
|
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdSetInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAFD_INFO InfoReq = LockRequest(Irp, IrpSp);
|
PAFD_INFO InfoReq = (PAFD_INFO)LockRequest(Irp, IrpSp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!InfoReq)
|
if (!InfoReq)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
_SEH2_TRY {
|
_SEH2_TRY
|
||||||
switch (InfoReq->InformationClass) {
|
{
|
||||||
case AFD_INFO_BLOCKING_MODE:
|
switch (InfoReq->InformationClass)
|
||||||
AFD_DbgPrint(MID_TRACE,("Blocking mode set to %d\n", InfoReq->Information.Ulong));
|
{
|
||||||
FCB->BlockingMode = InfoReq->Information.Ulong;
|
case AFD_INFO_BLOCKING_MODE:
|
||||||
break;
|
AFD_DbgPrint(MID_TRACE,("Blocking mode set to %d\n", InfoReq->Information.Ulong));
|
||||||
default:
|
FCB->BlockingMode = InfoReq->Information.Ulong;
|
||||||
AFD_DbgPrint(MIN_TRACE,("Unknown request %d\n", InfoReq->InformationClass));
|
break;
|
||||||
break;
|
default:
|
||||||
}
|
AFD_DbgPrint(MIN_TRACE,("Unknown request %d\n", InfoReq->InformationClass));
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
break;
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
}
|
||||||
} _SEH2_END;
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||||
|
|
||||||
return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdGetSockName(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PMDL Mdl = NULL;
|
PMDL Mdl = NULL;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if( FCB->AddressFile.Object == NULL && FCB->Connection.Object == NULL ) {
|
if (FCB->AddressFile.Object == NULL && FCB->Connection.Object == NULL)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
{
|
||||||
|
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
Mdl = IoAllocateMdl
|
Mdl = IoAllocateMdl
|
||||||
|
@ -141,44 +157,52 @@ AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if( Mdl != NULL ) {
|
if( Mdl != NULL )
|
||||||
_SEH2_TRY {
|
{
|
||||||
MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess );
|
_SEH2_TRY
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
{
|
||||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess );
|
||||||
Status = _SEH2_GetExceptionCode();
|
}
|
||||||
} _SEH2_END;
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if (NT_SUCCESS(Status))
|
||||||
Status = TdiQueryInformation
|
{
|
||||||
( FCB->Connection.Object ? FCB->Connection.Object : FCB->AddressFile.Object,
|
Status = TdiQueryInformation(
|
||||||
TDI_QUERY_ADDRESS_INFO,
|
FCB->Connection.Object ? FCB->Connection.Object : FCB->AddressFile.Object,
|
||||||
Mdl );
|
TDI_QUERY_ADDRESS_INFO,
|
||||||
|
Mdl );
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdGetPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdGetPeerName(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PMDL Mdl = NULL;
|
PMDL Mdl = NULL;
|
||||||
PTDI_CONNECTION_INFORMATION ConnInfo = NULL;
|
PTDI_CONNECTION_INFORMATION ConnInfo = NULL;
|
||||||
|
|
||||||
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (FCB->RemoteAddress == NULL || FCB->Connection.Object == NULL)
|
||||||
|
{
|
||||||
if (FCB->RemoteAddress == NULL || FCB->Connection.Object == NULL) {
|
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NT_SUCCESS(Status = TdiBuildNullConnectionInfo
|
if (NT_SUCCESS(Status = TdiBuildNullConnectionInfo(&ConnInfo,
|
||||||
(&ConnInfo,
|
|
||||||
FCB->RemoteAddress->Address[0].AddressType)))
|
FCB->RemoteAddress->Address[0].AddressType)))
|
||||||
{
|
{
|
||||||
Mdl = IoAllocateMdl(ConnInfo,
|
Mdl = IoAllocateMdl(ConnInfo,
|
||||||
|
@ -190,12 +214,16 @@ AfdGetPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
if (Mdl)
|
if (Mdl)
|
||||||
{
|
{
|
||||||
_SEH2_TRY {
|
_SEH2_TRY
|
||||||
MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoModifyAccess);
|
{
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoModifyAccess);
|
||||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
}
|
||||||
Status = _SEH2_GetExceptionCode();
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
} _SEH2_END;
|
{
|
||||||
|
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -205,8 +233,11 @@ AfdGetPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= TaLengthOfTransportAddress(ConnInfo->RemoteAddress))
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >=
|
||||||
RtlCopyMemory(Irp->UserBuffer, ConnInfo->RemoteAddress, TaLengthOfTransportAddress(ConnInfo->RemoteAddress));
|
TaLengthOfTransportAddress(ConnInfo->RemoteAddress))
|
||||||
|
RtlCopyMemory(Irp->UserBuffer,
|
||||||
|
ConnInfo->RemoteAddress,
|
||||||
|
TaLengthOfTransportAddress(ConnInfo->RemoteAddress));
|
||||||
else
|
else
|
||||||
Status = STATUS_BUFFER_TOO_SMALL;
|
Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,15 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
|
static
|
||||||
PIRP Irp,
|
NTSTATUS
|
||||||
PFILE_OBJECT NewFileObject,
|
SatisfyAccept
|
||||||
PAFD_TDI_OBJECT_QELT Qelt ) {
|
( PAFD_DEVICE_EXTENSION DeviceExt,
|
||||||
PAFD_FCB FCB = NewFileObject->FsContext;
|
PIRP Irp,
|
||||||
|
PFILE_OBJECT NewFileObject,
|
||||||
|
PAFD_TDI_OBJECT_QELT Qelt )
|
||||||
|
{
|
||||||
|
PAFD_FCB FCB = (PAFD_FCB)NewFileObject->FsContext;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
|
@ -28,14 +32,15 @@ static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
FCB->Connection = Qelt->Object;
|
FCB->Connection = Qelt->Object;
|
||||||
|
|
||||||
if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
|
if (FCB->RemoteAddress)
|
||||||
FCB->RemoteAddress =
|
ExFreePool( FCB->RemoteAddress );
|
||||||
TaCopyTransportAddress( Qelt->ConnInfo->RemoteAddress );
|
|
||||||
|
FCB->RemoteAddress = TaCopyTransportAddress(Qelt->ConnInfo->RemoteAddress);
|
||||||
|
|
||||||
if( !FCB->RemoteAddress )
|
if (!FCB->RemoteAddress)
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
else
|
else
|
||||||
Status = MakeSocketIntoConnection( FCB );
|
Status = MakeSocketIntoConnection( FCB );
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, FCB->RemoteAddress);
|
Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, FCB->RemoteAddress);
|
||||||
|
@ -43,7 +48,9 @@ static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt )
|
static
|
||||||
|
NTSTATUS
|
||||||
|
SatisfyPreAccept(PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt)
|
||||||
{
|
{
|
||||||
PAFD_RECEIVED_ACCEPT_DATA ListenReceive =
|
PAFD_RECEIVED_ACCEPT_DATA ListenReceive =
|
||||||
(PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
|
(PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
@ -110,7 +117,10 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt )
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI ListenComplete
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ListenComplete
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
PVOID Context )
|
PVOID Context )
|
||||||
|
@ -173,7 +183,7 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
DbgPrint("[AFD, ListenComplete] IoStatus was %x\n", FCB->ListenIrp.Iosb.Status);
|
DbgPrint("[AFD, ListenComplete] IoStatus was %x\n", FCB->ListenIrp.Iosb.Status);
|
||||||
|
|
||||||
Qelt = ExAllocatePool( NonPagedPool, sizeof(AFD_TDI_OBJECT_QELT) );//sizeof(*Qelt) );
|
Qelt = ExAllocatePool( NonPagedPool, sizeof(AFD_TDI_OBJECT_QELT) );//sizeof(*Qelt) );
|
||||||
if( !Qelt )
|
if (!Qelt)
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +213,7 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Satisfy a pre-accept request if one is available */
|
/* Satisfy a pre-accept request if one is available */
|
||||||
if ( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
|
if (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
|
||||||
!IsListEmpty( &FCB->PendingConnections ) )
|
!IsListEmpty( &FCB->PendingConnections ) )
|
||||||
{
|
{
|
||||||
PLIST_ENTRY PendingIrp = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
|
PLIST_ENTRY PendingIrp = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
|
||||||
|
@ -244,7 +254,7 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger a select return if appropriate */
|
/* Trigger a select return if appropriate */
|
||||||
if ( !IsListEmpty( &FCB->PendingConnections ) )
|
if (!IsListEmpty( &FCB->PendingConnections))
|
||||||
{
|
{
|
||||||
FCB->PollState |= AFD_EVENT_ACCEPT;
|
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||||
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
||||||
|
@ -265,19 +275,19 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_LISTEN_DATA ListenReq;
|
PAFD_LISTEN_DATA ListenReq;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on 0x%x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on 0x%x\n", FCB));
|
||||||
DbgPrint("[AfdListenSocket] Called on 0x%x\n", FCB);
|
DbgPrint("[AfdListenSocket] Called on 0x%x\n", FCB);
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if ( !SocketAcquireStateLock(FCB) )
|
||||||
return LostSocket( Irp );
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if( !(ListenReq = LockRequest( Irp, IrpSp )) )
|
if ( !(ListenReq = (PAFD_LISTEN_DATA)LockRequest(Irp, IrpSp)) )
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
|
||||||
if( FCB->State != SOCKET_STATE_BOUND )
|
if (FCB->State != SOCKET_STATE_BOUND)
|
||||||
{
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
AFD_DbgPrint(MID_TRACE,("Could not listen an unbound socket\n"));
|
AFD_DbgPrint(MID_TRACE,("Could not listen an unbound socket\n"));
|
||||||
|
@ -294,7 +304,7 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status));
|
||||||
DbgPrint("[AfdListenSocket] Status from warmsocket 0x%x\n", Status);
|
DbgPrint("[AfdListenSocket] Status from warmsocket 0x%x\n", Status);
|
||||||
|
|
||||||
if ( !NT_SUCCESS(Status) )
|
if (!NT_SUCCESS(Status))
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
|
|
||||||
Status = TdiBuildNullConnectionInfo(&FCB->ListenIrp.ConnectionCallInfo,
|
Status = TdiBuildNullConnectionInfo(&FCB->ListenIrp.ConnectionCallInfo,
|
||||||
|
@ -336,28 +346,26 @@ NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp )
|
PIO_STACK_LOCATION IrpSp )
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return LostSocket( Irp );
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->PendingConnections ) )
|
if (!IsListEmpty(&FCB->PendingConnections))
|
||||||
{
|
{
|
||||||
PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
|
PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
|
||||||
|
|
||||||
/* We have a pending connection ... complete this irp right away */
|
/* We have a pending connection ... complete this irp right away */
|
||||||
Status = SatisfyPreAccept
|
Status = SatisfyPreAccept(Irp,
|
||||||
( Irp,
|
CONTAINING_RECORD(PendingConn, AFD_TDI_OBJECT_QELT, ListEntry));
|
||||||
CONTAINING_RECORD
|
|
||||||
( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) );
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
|
AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
|
||||||
DbgPrint("[AfdWaitForListen] Completed a wait for accept\n");
|
DbgPrint("[AfdWaitForListen] Completed a wait for accept\n");
|
||||||
|
|
||||||
if ( !IsListEmpty( &FCB->PendingConnections ) )
|
if (!IsListEmpty(&FCB->PendingConnections))
|
||||||
{
|
{
|
||||||
FCB->PollState |= AFD_EVENT_ACCEPT;
|
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||||
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
||||||
|
@ -386,7 +394,8 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PAFD_DEVICE_EXTENSION DeviceExt =
|
PAFD_DEVICE_EXTENSION DeviceExt =
|
||||||
(PAFD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
(PAFD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_ACCEPT_DATA AcceptData = Irp->AssociatedIrp.SystemBuffer;
|
PAFD_ACCEPT_DATA AcceptData =
|
||||||
|
(PAFD_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
|
||||||
PLIST_ENTRY PendingConn;
|
PLIST_ENTRY PendingConn;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
@ -398,7 +407,7 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return LostSocket( Irp );
|
return LostSocket( Irp );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( PendingConn = FCB->PendingConnections.Flink;
|
for (PendingConn = FCB->PendingConnections.Flink;
|
||||||
PendingConn != &FCB->PendingConnections;
|
PendingConn != &FCB->PendingConnections;
|
||||||
PendingConn = PendingConn->Flink )
|
PendingConn = PendingConn->Flink )
|
||||||
{
|
{
|
||||||
|
@ -412,11 +421,11 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
AcceptData->SequenceNumber,
|
AcceptData->SequenceNumber,
|
||||||
PendingConnObj->Seq);
|
PendingConnObj->Seq);
|
||||||
|
|
||||||
if( PendingConnObj->Seq == AcceptData->SequenceNumber )
|
if (PendingConnObj->Seq == AcceptData->SequenceNumber)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT NewFileObject = NULL;
|
PFILE_OBJECT NewFileObject = NULL;
|
||||||
|
|
||||||
RemoveEntryList( PendingConn );
|
RemoveEntryList(PendingConn);
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle( AcceptData->ListenHandle,
|
Status = ObReferenceObjectByHandle( AcceptData->ListenHandle,
|
||||||
FILE_ALL_ACCESS,
|
FILE_ALL_ACCESS,
|
||||||
|
@ -425,7 +434,7 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
(PVOID *)&NewFileObject,
|
(PVOID *)&NewFileObject,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if (!NT_SUCCESS(Status))
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
|
|
||||||
ASSERT(NewFileObject != FileObject);
|
ASSERT(NewFileObject != FileObject);
|
||||||
|
@ -441,16 +450,16 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
ExFreePool( PendingConnObj );
|
ExFreePool( PendingConnObj );
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->PendingConnections ) )
|
if (!IsListEmpty( &FCB->PendingConnections))
|
||||||
{
|
{
|
||||||
FCB->PollState |= AFD_EVENT_ACCEPT;
|
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||||
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval(FCB->DeviceExt, FCB->FileObject);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FCB->PollState &= ~AFD_EVENT_ACCEPT;
|
FCB->PollState &= ~AFD_EVENT_ACCEPT;
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock(FCB);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
|
/* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
|
||||||
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
|
||||||
|
{
|
||||||
BOOLEAN LockFailed = FALSE;
|
BOOLEAN LockFailed = FALSE;
|
||||||
|
|
||||||
ASSERT(!Irp->MdlAddress);
|
ASSERT(!Irp->MdlAddress);
|
||||||
|
@ -40,19 +41,27 @@ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL );
|
NULL );
|
||||||
if( Irp->MdlAddress ) {
|
if( Irp->MdlAddress )
|
||||||
_SEH2_TRY {
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
|
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
LockFailed = TRUE;
|
LockFailed = TRUE;
|
||||||
} _SEH2_END;
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
if( LockFailed ) {
|
if (LockFailed)
|
||||||
IoFreeMdl( Irp->MdlAddress );
|
{
|
||||||
|
IoFreeMdl(Irp->MdlAddress);
|
||||||
Irp->MdlAddress = NULL;
|
Irp->MdlAddress = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else return NULL;
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRP_MJ_READ:
|
case IRP_MJ_READ:
|
||||||
|
@ -66,19 +75,27 @@ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL );
|
NULL );
|
||||||
if( Irp->MdlAddress ) {
|
if (Irp->MdlAddress)
|
||||||
_SEH2_TRY {
|
{
|
||||||
MmProbeAndLockPages( Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess );
|
_SEH2_TRY
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
{
|
||||||
|
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, IoModifyAccess);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
LockFailed = TRUE;
|
LockFailed = TRUE;
|
||||||
} _SEH2_END;
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
if( LockFailed ) {
|
if (LockFailed)
|
||||||
IoFreeMdl( Irp->MdlAddress );
|
{
|
||||||
|
IoFreeMdl(Irp->MdlAddress);
|
||||||
Irp->MdlAddress = NULL;
|
Irp->MdlAddress = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else return NULL;
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -89,7 +106,7 @@ PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
|
||||||
return GetLockedData(Irp, IrpSp);
|
return GetLockedData(Irp, IrpSp);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
|
VOID UnlockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
ASSERT(Irp->MdlAddress);
|
ASSERT(Irp->MdlAddress);
|
||||||
MmUnlockPages( Irp->MdlAddress );
|
MmUnlockPages( Irp->MdlAddress );
|
||||||
|
@ -101,28 +118,36 @@ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
|
||||||
* treat the address buffer as an ordinary client buffer. It's only used
|
* treat the address buffer as an ordinary client buffer. It's only used
|
||||||
* for datagrams. */
|
* for datagrams. */
|
||||||
|
|
||||||
PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
PAFD_WSABUF
|
||||||
PVOID AddressBuf, PINT AddressLen,
|
LockBuffers
|
||||||
BOOLEAN Write, BOOLEAN LockAddress ) {
|
( PAFD_WSABUF Buf, UINT Count,
|
||||||
|
PVOID AddressBuf, PINT AddressLen,
|
||||||
|
BOOLEAN Write, BOOLEAN LockAddress )
|
||||||
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
/* Copy the buffer array so we don't lose it */
|
/* Copy the buffer array so we don't lose it */
|
||||||
UINT Lock = LockAddress ? 2 : 0;
|
UINT Lock = LockAddress ? 2 : 0;
|
||||||
UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
|
UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
|
||||||
PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
|
PAFD_WSABUF NewBuf = (PAFD_WSABUF)ExAllocatePool(PagedPool, Size * 2);
|
||||||
BOOLEAN LockFailed = FALSE;
|
BOOLEAN LockFailed = FALSE;
|
||||||
PAFD_MAPBUF MapBuf;
|
PAFD_MAPBUF MapBuf;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called(%08x)\n", NewBuf));
|
AFD_DbgPrint(MID_TRACE,("Called(%08x)\n", NewBuf));
|
||||||
|
|
||||||
if( NewBuf ) {
|
if (NewBuf)
|
||||||
|
{
|
||||||
RtlZeroMemory(NewBuf, Size * 2);
|
RtlZeroMemory(NewBuf, Size * 2);
|
||||||
|
|
||||||
MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
|
MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
|
||||||
|
|
||||||
_SEH2_TRY {
|
_SEH2_TRY
|
||||||
RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
|
{
|
||||||
if( LockAddress ) {
|
RtlCopyMemory(NewBuf, Buf, sizeof(AFD_WSABUF) * Count);
|
||||||
if (AddressBuf && AddressLen) {
|
|
||||||
|
if (LockAddress)
|
||||||
|
{
|
||||||
|
if (AddressBuf && AddressLen)
|
||||||
|
{
|
||||||
NewBuf[Count].buf = AddressBuf;
|
NewBuf[Count].buf = AddressBuf;
|
||||||
NewBuf[Count].len = *AddressLen;
|
NewBuf[Count].len = *AddressLen;
|
||||||
NewBuf[Count + 1].buf = (PVOID)AddressLen;
|
NewBuf[Count + 1].buf = (PVOID)AddressLen;
|
||||||
|
@ -130,52 +155,68 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
||||||
}
|
}
|
||||||
Count += 2;
|
Count += 2;
|
||||||
}
|
}
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info "
|
AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info "
|
||||||
"from userland (%x %x)\n",
|
"from userland (%x %x)\n",
|
||||||
Buf, AddressLen));
|
Buf, AddressLen));
|
||||||
ExFreePool( NewBuf );
|
ExFreePool(NewBuf);
|
||||||
_SEH2_YIELD(return NULL);
|
_SEH2_YIELD(return NULL);
|
||||||
} _SEH2_END;
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
for( i = 0; i < Count; i++ ) {
|
for (i = 0; i < Count; i++)
|
||||||
AFD_DbgPrint(MID_TRACE,("Locking buffer %d (%x:%d)\n",
|
{
|
||||||
i, NewBuf[i].buf, NewBuf[i].len));
|
AFD_DbgPrint(MID_TRACE,("Locking buffer %d (%x:%d)\n",
|
||||||
|
i, NewBuf[i].buf, NewBuf[i].len));
|
||||||
|
|
||||||
if( NewBuf[i].buf && NewBuf[i].len ) {
|
if (NewBuf[i].buf && NewBuf[i].len)
|
||||||
MapBuf[i].Mdl = IoAllocateMdl( NewBuf[i].buf,
|
{
|
||||||
NewBuf[i].len,
|
MapBuf[i].Mdl = IoAllocateMdl( NewBuf[i].buf,
|
||||||
FALSE,
|
NewBuf[i].len,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL );
|
FALSE,
|
||||||
} else {
|
NULL );
|
||||||
MapBuf[i].Mdl = NULL;
|
}
|
||||||
continue;
|
else
|
||||||
|
{
|
||||||
|
MapBuf[i].Mdl = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("NewMdl @ %x\n", MapBuf[i].Mdl));
|
||||||
|
|
||||||
|
if (MapBuf[i].Mdl)
|
||||||
|
{
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
|
||||||
|
Write ? IoModifyAccess : IoReadAccess );
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
LockFailed = TRUE;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("MmProbeAndLock finished\n"));
|
||||||
|
|
||||||
|
if (LockFailed)
|
||||||
|
{
|
||||||
|
IoFreeMdl( MapBuf[i].Mdl );
|
||||||
|
MapBuf[i].Mdl = NULL;
|
||||||
|
ExFreePool( NewBuf );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExFreePool( NewBuf );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("NewMdl @ %x\n", MapBuf[i].Mdl));
|
|
||||||
|
|
||||||
if( MapBuf[i].Mdl ) {
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
|
|
||||||
_SEH2_TRY {
|
|
||||||
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
|
|
||||||
Write ? IoModifyAccess : IoReadAccess );
|
|
||||||
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
|
||||||
LockFailed = TRUE;
|
|
||||||
} _SEH2_END;
|
|
||||||
AFD_DbgPrint(MID_TRACE,("MmProbeAndLock finished\n"));
|
|
||||||
|
|
||||||
if( LockFailed ) {
|
|
||||||
IoFreeMdl( MapBuf[i].Mdl );
|
|
||||||
MapBuf[i].Mdl = NULL;
|
|
||||||
ExFreePool( NewBuf );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ExFreePool( NewBuf );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Leaving %x\n", NewBuf));
|
AFD_DbgPrint(MID_TRACE,("Leaving %x\n", NewBuf));
|
||||||
|
@ -183,75 +224,90 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
|
||||||
return NewBuf;
|
return NewBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address ) {
|
VOID UnlockBuffers(PAFD_WSABUF Buf, UINT Count, BOOL Address)
|
||||||
|
{
|
||||||
UINT Lock = Address ? 2 : 0;
|
UINT Lock = Address ? 2 : 0;
|
||||||
PAFD_MAPBUF Map = (PAFD_MAPBUF)(Buf + Count + Lock);
|
PAFD_MAPBUF Map = (PAFD_MAPBUF)(Buf + Count + Lock);
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
if( !Buf ) return;
|
if (!Buf)
|
||||||
|
return;
|
||||||
|
|
||||||
for( i = 0; i < Count + Lock; i++ ) {
|
for (i=0; i < Count + Lock; i++)
|
||||||
if( Map[i].Mdl ) {
|
{
|
||||||
MmUnlockPages( Map[i].Mdl );
|
if (Map[i].Mdl)
|
||||||
IoFreeMdl( Map[i].Mdl );
|
{
|
||||||
Map[i].Mdl = NULL;
|
MmUnlockPages( Map[i].Mdl );
|
||||||
}
|
IoFreeMdl( Map[i].Mdl );
|
||||||
|
Map[i].Mdl = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExFreePool( Buf );
|
ExFreePool(Buf);
|
||||||
Buf = NULL;
|
Buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Produce a kernel-land handle array with handles replaced by object
|
/* Produce a kernel-land handle array with handles replaced by object
|
||||||
* pointers. This will allow the system to do proper alerting */
|
* pointers. This will allow the system to do proper alerting */
|
||||||
PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
|
PAFD_HANDLE LockHandles(PAFD_HANDLE HandleArray, UINT HandleCount)
|
||||||
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAFD_HANDLE FileObjects = ExAllocatePool
|
PAFD_HANDLE FileObjects =
|
||||||
( NonPagedPool, HandleCount * sizeof(AFD_HANDLE) );
|
(PAFD_HANDLE)ExAllocatePool(NonPagedPool, HandleCount * sizeof(AFD_HANDLE));
|
||||||
|
|
||||||
for( i = 0; FileObjects && i < HandleCount; i++ ) {
|
for (i=0; FileObjects && i < HandleCount; i++)
|
||||||
FileObjects[i].Status = 0;
|
{
|
||||||
FileObjects[i].Events = HandleArray[i].Events;
|
FileObjects[i].Status = 0;
|
||||||
|
FileObjects[i].Events = HandleArray[i].Events;
|
||||||
FileObjects[i].Handle = 0;
|
FileObjects[i].Handle = 0;
|
||||||
if( !HandleArray[i].Handle ) continue;
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if (!HandleArray[i].Handle)
|
||||||
Status = ObReferenceObjectByHandle
|
continue;
|
||||||
( (PVOID)HandleArray[i].Handle,
|
|
||||||
FILE_ALL_ACCESS,
|
if (NT_SUCCESS(Status))
|
||||||
NULL,
|
{
|
||||||
KernelMode,
|
Status = ObReferenceObjectByHandle
|
||||||
(PVOID*)&FileObjects[i].Handle,
|
( (PVOID)HandleArray[i].Handle,
|
||||||
NULL );
|
FILE_ALL_ACCESS,
|
||||||
}
|
NULL,
|
||||||
|
KernelMode,
|
||||||
|
(PVOID*)&FileObjects[i].Handle,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if (!NT_SUCCESS(Status))
|
||||||
FileObjects[i].Handle = 0;
|
FileObjects[i].Handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) ) {
|
if (!NT_SUCCESS(Status))
|
||||||
UnlockHandles( FileObjects, HandleCount );
|
{
|
||||||
return NULL;
|
UnlockHandles(FileObjects, HandleCount);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FileObjects;
|
return FileObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
|
VOID UnlockHandles(PAFD_HANDLE HandleArray, UINT HandleCount)
|
||||||
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
for( i = 0; i < HandleCount; i++ ) {
|
for (i = 0; i < HandleCount; i++)
|
||||||
if( HandleArray[i].Handle )
|
{
|
||||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
if (HandleArray[i].Handle)
|
||||||
|
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
ExFreePool( HandleArray );
|
ExFreePool(HandleArray);
|
||||||
HandleArray = NULL;
|
HandleArray = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB ) {
|
BOOLEAN SocketAcquireStateLock(PAFD_FCB FCB)
|
||||||
if( !FCB ) return FALSE;
|
{
|
||||||
|
if (!FCB )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return !KeWaitForMutexObject(&FCB->Mutex,
|
return !KeWaitForMutexObject(&FCB->Mutex,
|
||||||
Executive,
|
Executive,
|
||||||
|
@ -260,34 +316,50 @@ BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB ) {
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID SocketStateUnlock( PAFD_FCB FCB ) {
|
VOID SocketStateUnlock(PAFD_FCB FCB)
|
||||||
|
{
|
||||||
KeReleaseMutex(&FCB->Mutex, FALSE);
|
KeReleaseMutex(&FCB->Mutex, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI UnlockAndMaybeComplete
|
NTSTATUS
|
||||||
( PAFD_FCB FCB, NTSTATUS Status, PIRP Irp,
|
NTAPI
|
||||||
UINT Information ) {
|
UnlockAndMaybeComplete
|
||||||
|
( PAFD_FCB FCB,
|
||||||
|
NTSTATUS Status,
|
||||||
|
PIRP Irp,
|
||||||
|
UINT Information )
|
||||||
|
{
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = Information;
|
Irp->IoStatus.Information = Information;
|
||||||
if ( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
|
|
||||||
|
if (Irp->MdlAddress)
|
||||||
|
UnlockRequest( Irp, IoGetCurrentIrpStackLocation(Irp));
|
||||||
|
|
||||||
(void)IoSetCancelRoutine(Irp, NULL);
|
(void)IoSetCancelRoutine(Irp, NULL);
|
||||||
SocketStateUnlock( FCB );
|
|
||||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
SocketStateUnlock(FCB);
|
||||||
|
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS LostSocket( PIRP Irp ) {
|
NTSTATUS LostSocket(PIRP Irp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_FILE_CLOSED;
|
NTSTATUS Status = STATUS_FILE_CLOSED;
|
||||||
AFD_DbgPrint(MIN_TRACE,("Called.\n"));
|
AFD_DbgPrint(MIN_TRACE,("Called.\n"));
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
if ( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
|
|
||||||
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
if (Irp->MdlAddress)
|
||||||
|
UnlockRequest(Irp, IoGetCurrentIrpStackLocation(Irp));
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
|
NTSTATUS LeaveIrpUntilLater(PAFD_FCB FCB, PIRP Irp, UINT Function)
|
||||||
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Add the IRP to the queue in all cases (so AfdCancelHandler will work properly) */
|
/* Add the IRP to the queue in all cases (so AfdCancelHandler will work properly) */
|
||||||
|
@ -314,12 +386,11 @@ NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
|
||||||
* so we are to call the cancel routine ourselves right here to cancel the IRP
|
* so we are to call the cancel routine ourselves right here to cancel the IRP
|
||||||
* (which handles all the stuff we do above) and return STATUS_CANCELLED to the caller
|
* (which handles all the stuff we do above) and return STATUS_CANCELLED to the caller
|
||||||
*/
|
*/
|
||||||
AfdCancelHandler(IoGetCurrentIrpStackLocation(Irp)->DeviceObject,
|
AfdCancelHandler(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
|
||||||
Irp);
|
|
||||||
Status = STATUS_CANCELLED;
|
Status = STATUS_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock(FCB);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,27 +25,14 @@ DWORD DebugTraceLevel = 0;
|
||||||
|
|
||||||
#endif /* DBG */
|
#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 */
|
/* FUNCTIONS */
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
|
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +40,8 @@ AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (FCB->DisconnectOptionsSize == 0)
|
if (FCB->DisconnectOptionsSize == 0)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
|
@ -79,7 +67,8 @@ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PVOID DisconnectOptions = LockRequest(Irp, IrpSp);
|
PVOID DisconnectOptions = LockRequest(Irp, IrpSp);
|
||||||
UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!DisconnectOptions)
|
if (!DisconnectOptions)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -116,7 +105,8 @@ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PUINT DisconnectOptionsSize = (PUINT)LockRequest(Irp, IrpSp);
|
PUINT DisconnectOptionsSize = (PUINT)LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!DisconnectOptionsSize)
|
if (!DisconnectOptionsSize)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -141,7 +131,8 @@ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
@ -149,14 +140,16 @@ AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (FCB->DisconnectDataSize == 0)
|
if (FCB->DisconnectDataSize == 0)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
|
|
||||||
ASSERT(FCB->DisconnectData);
|
ASSERT(FCB->DisconnectData);
|
||||||
|
|
||||||
if (FCB->FilledDisconnectData < BufferSize) BufferSize = FCB->FilledDisconnectData;
|
if (FCB->FilledDisconnectData < BufferSize)
|
||||||
|
BufferSize = FCB->FilledDisconnectData;
|
||||||
|
|
||||||
RtlCopyMemory(Irp->UserBuffer,
|
RtlCopyMemory(Irp->UserBuffer,
|
||||||
FCB->DisconnectData,
|
FCB->DisconnectData,
|
||||||
|
@ -171,11 +164,12 @@ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PVOID DisconnectData = LockRequest(Irp, IrpSp);
|
PVOID DisconnectData = LockRequest(Irp, IrpSp);
|
||||||
UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!DisconnectData)
|
if (!DisconnectData)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -208,11 +202,12 @@ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PUINT DisconnectDataSize = LockRequest(Irp, IrpSp);
|
PUINT DisconnectDataSize = (PUINT)LockRequest(Irp, IrpSp);
|
||||||
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if (!DisconnectDataSize)
|
if (!DisconnectDataSize)
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
|
@ -237,13 +232,15 @@ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PULONG HandleFlags = LockRequest(Irp, IrpSp);
|
PULONG HandleFlags = (PULONG)LockRequest(Irp, IrpSp);
|
||||||
PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
|
PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
|
||||||
|
@ -264,7 +261,9 @@ AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
@ -291,7 +290,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
EaInfo = Irp->AssociatedIrp.SystemBuffer;
|
EaInfo = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
if( EaInfo )
|
if (EaInfo)
|
||||||
{
|
{
|
||||||
ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
|
ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
|
||||||
EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
|
EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
|
||||||
|
@ -306,17 +305,18 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n"));
|
AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n"));
|
||||||
|
|
||||||
FCB = ExAllocatePool(NonPagedPool, sizeof(AFD_FCB));
|
FCB = (PAFD_FCB)ExAllocatePool(NonPagedPool, sizeof(AFD_FCB));
|
||||||
RtlZeroMemory(FCB, sizeof(AFD_FCB));
|
RtlZeroMemory(FCB, sizeof(AFD_FCB));
|
||||||
|
|
||||||
if( FCB == NULL )
|
if (FCB == NULL)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0));
|
AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n",
|
||||||
|
FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0));
|
||||||
|
|
||||||
RtlZeroMemory( FCB, sizeof( *FCB ) );
|
RtlZeroMemory( FCB, sizeof( *FCB ) );
|
||||||
|
|
||||||
|
@ -329,32 +329,33 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
|
FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
|
||||||
FCB->Connection.Handle = INVALID_HANDLE_VALUE;
|
FCB->Connection.Handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
KeInitializeMutex( &FCB->Mutex, 0 );
|
KeInitializeMutex(&FCB->Mutex, 0);
|
||||||
|
|
||||||
for( i = 0; i < MAX_FUNCTIONS; i++ )
|
for (i=0; i < MAX_FUNCTIONS; i++)
|
||||||
{
|
{
|
||||||
InitializeListHead( &FCB->PendingIrpList[i] );
|
InitializeListHead(&FCB->PendingIrpList[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeListHead( &FCB->DatagramList );
|
InitializeListHead(&FCB->DatagramList);
|
||||||
InitializeListHead( &FCB->PendingConnections );
|
InitializeListHead(&FCB->PendingConnections);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
|
||||||
|
|
||||||
if( ConnectInfo )
|
if (ConnectInfo)
|
||||||
{
|
{
|
||||||
FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
|
FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
|
||||||
FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
|
FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
|
||||||
FCB->TdiDeviceName.Buffer =
|
FCB->TdiDeviceName.Buffer = ExAllocatePool(NonPagedPool, FCB->TdiDeviceName.Length);
|
||||||
ExAllocatePool( NonPagedPool, FCB->TdiDeviceName.Length );
|
|
||||||
RtlZeroMemory(FCB->TdiDeviceName.Buffer, FCB->TdiDeviceName.Length);
|
RtlZeroMemory(FCB->TdiDeviceName.Buffer, FCB->TdiDeviceName.Length);
|
||||||
|
|
||||||
if( !FCB->TdiDeviceName.Buffer )
|
if (!FCB->TdiDeviceName.Buffer)
|
||||||
{
|
{
|
||||||
ExFreePool(FCB);
|
ExFreePool(FCB);
|
||||||
AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
|
AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
|
||||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
|
||||||
|
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +374,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
FileObject->FsContext = FCB;
|
FileObject->FsContext = FCB;
|
||||||
|
|
||||||
/* It seems that UDP sockets are writable from inception */
|
/* It seems that UDP sockets are writable from inception */
|
||||||
if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
|
if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
|
AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
|
||||||
|
|
||||||
|
@ -383,11 +384,11 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if( FCB->TdiDeviceName.Buffer )
|
if (FCB->TdiDeviceName.Buffer)
|
||||||
ExFreePool( FCB->TdiDeviceName.Buffer );
|
ExFreePool( FCB->TdiDeviceName.Buffer);
|
||||||
ExFreePool( FCB );
|
ExFreePool(FCB);
|
||||||
FileObject->FsContext = NULL;
|
FileObject->FsContext = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,9 +400,10 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTSTATUS
|
||||||
PIO_STACK_LOCATION IrpSp)
|
NTAPI
|
||||||
|
AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
|
@ -411,7 +413,7 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCleanupSocket] Called\n");
|
DbgPrint("[AFD, AfdCleanupSocket] Called\n");
|
||||||
|
|
||||||
if ( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return LostSocket(Irp);
|
return LostSocket(Irp);
|
||||||
|
|
||||||
for (Function = 0; Function < MAX_FUNCTIONS; Function++)
|
for (Function = 0; Function < MAX_FUNCTIONS; Function++)
|
||||||
|
@ -437,7 +439,9 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp)
|
PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
@ -449,11 +453,10 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PLIST_ENTRY QeltEntry;
|
PLIST_ENTRY QeltEntry;
|
||||||
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,
|
AFD_DbgPrint(MID_TRACE, ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
|
||||||
("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Called\n");
|
DbgPrint("[AFD, AfdCloseSocket] Called\n");
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Setting closed state\n");
|
DbgPrint("[AFD, AfdCloseSocket] Setting closed state\n");
|
||||||
|
@ -468,9 +471,9 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Canceling in flight requests (AFD -> tcpip)\n");
|
DbgPrint("[AFD, AfdCloseSocket] Canceling in flight requests (AFD -> tcpip)\n");
|
||||||
/* Cancel our pending _In Flight_ IRPs
|
/* Cancel our pending _In Flight_ IRPs
|
||||||
That is IRPs from AFD -> tcpip*/
|
That is IRPs from AFD -> tcpip*/
|
||||||
for( i = 0; i < IN_FLIGHT_REQUESTS; i++ )
|
for (i=0; i < IN_FLIGHT_REQUESTS; i++)
|
||||||
{
|
{
|
||||||
if( InFlightRequest[i]->InFlightRequest )
|
if (InFlightRequest[i]->InFlightRequest)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
|
AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
|
||||||
i, InFlightRequest[i]->InFlightRequest));
|
i, InFlightRequest[i]->InFlightRequest));
|
||||||
|
@ -502,56 +505,56 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Doing final cleanups\n");
|
DbgPrint("[AFD, AfdCloseSocket] Doing final cleanups\n");
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock(FCB);
|
||||||
|
|
||||||
if( FCB->EventSelect )
|
if (FCB->EventSelect)
|
||||||
ObDereferenceObject( FCB->EventSelect );
|
ObDereferenceObject(FCB->EventSelect);
|
||||||
|
|
||||||
if( FCB->Context )
|
if (FCB->Context)
|
||||||
ExFreePool( FCB->Context );
|
ExFreePool(FCB->Context);
|
||||||
|
|
||||||
if( FCB->Recv.Window )
|
if (FCB->Recv.Window)
|
||||||
ExFreePool( FCB->Recv.Window );
|
ExFreePool(FCB->Recv.Window);
|
||||||
|
|
||||||
if( FCB->Send.Window )
|
if (FCB->Send.Window)
|
||||||
ExFreePool( FCB->Send.Window );
|
ExFreePool(FCB->Send.Window);
|
||||||
|
|
||||||
if( FCB->AddressFrom )
|
if ( FCB->AddressFrom )
|
||||||
ExFreePool( FCB->AddressFrom );
|
ExFreePool(FCB->AddressFrom);
|
||||||
|
|
||||||
if( FCB->ConnectInfo )
|
if (FCB->ConnectInfo)
|
||||||
ExFreePool( FCB->ConnectInfo );
|
ExFreePool(FCB->ConnectInfo);
|
||||||
|
|
||||||
if( FCB->ConnectData )
|
if (FCB->ConnectData)
|
||||||
ExFreePool( FCB->ConnectData );
|
ExFreePool(FCB->ConnectData);
|
||||||
|
|
||||||
if( FCB->DisconnectData )
|
if (FCB->DisconnectData)
|
||||||
ExFreePool( FCB->DisconnectData );
|
ExFreePool(FCB->DisconnectData);
|
||||||
|
|
||||||
if( FCB->ConnectOptions )
|
if (FCB->ConnectOptions)
|
||||||
ExFreePool( FCB->ConnectOptions );
|
ExFreePool(FCB->ConnectOptions);
|
||||||
|
|
||||||
if( FCB->DisconnectOptions )
|
if (FCB->DisconnectOptions)
|
||||||
ExFreePool( FCB->DisconnectOptions );
|
ExFreePool(FCB->DisconnectOptions);
|
||||||
|
|
||||||
if( FCB->LocalAddress )
|
if (FCB->LocalAddress)
|
||||||
ExFreePool( FCB->LocalAddress );
|
ExFreePool(FCB->LocalAddress);
|
||||||
|
|
||||||
if( FCB->RemoteAddress )
|
if (FCB->RemoteAddress)
|
||||||
ExFreePool( FCB->RemoteAddress );
|
ExFreePool(FCB->RemoteAddress);
|
||||||
|
|
||||||
if( FCB->Connection.Object )
|
if (FCB->Connection.Object)
|
||||||
{
|
{
|
||||||
TdiDisassociateAddressFile(FCB->Connection.Object);
|
TdiDisassociateAddressFile(FCB->Connection.Object);
|
||||||
ObDereferenceObject(FCB->Connection.Object);
|
ObDereferenceObject(FCB->Connection.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FCB->AddressFile.Object )
|
if (FCB->AddressFile.Object)
|
||||||
ObDereferenceObject(FCB->AddressFile.Object);
|
ObDereferenceObject(FCB->AddressFile.Object);
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Closing FCB->AddressFile.Handle\n");
|
DbgPrint("[AFD, AfdCloseSocket] Closing FCB->AddressFile.Handle\n");
|
||||||
|
|
||||||
if( FCB->AddressFile.Handle != INVALID_HANDLE_VALUE )
|
if (FCB->AddressFile.Handle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
|
if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
|
@ -562,7 +565,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Closing FCB->Connection.Handle\n");
|
DbgPrint("[AFD, AfdCloseSocket] Closing FCB->Connection.Handle\n");
|
||||||
|
|
||||||
if( FCB->Connection.Handle != INVALID_HANDLE_VALUE )
|
if (FCB->Connection.Handle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
|
if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
|
@ -573,7 +576,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Freeing FCB->TdiDeviceName.Buffer\n");
|
DbgPrint("[AFD, AfdCloseSocket] Freeing FCB->TdiDeviceName.Buffer\n");
|
||||||
|
|
||||||
if( FCB->TdiDeviceName.Buffer )
|
if (FCB->TdiDeviceName.Buffer)
|
||||||
ExFreePool(FCB->TdiDeviceName.Buffer);
|
ExFreePool(FCB->TdiDeviceName.Buffer);
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCloseSocket] Freeing FCB\n");
|
DbgPrint("[AFD, AfdCloseSocket] Freeing FCB\n");
|
||||||
|
@ -590,44 +593,43 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTSTATUS
|
||||||
PIO_STACK_LOCATION IrpSp)
|
NTAPI
|
||||||
|
AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_DISCONNECT_INFO DisReq;
|
PAFD_DISCONNECT_INFO DisReq;
|
||||||
IO_STATUS_BLOCK Iosb;
|
IO_STATUS_BLOCK Iosb;
|
||||||
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
|
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
USHORT Flags = 0;
|
USHORT Flags = 0;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
if( !(DisReq = LockRequest( Irp, IrpSp )) )
|
if (!(DisReq = LockRequest(Irp, IrpSp)))
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
Irp, 0 );
|
|
||||||
|
|
||||||
if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
|
if ( DisReq->DisconnectType & AFD_DISCONNECT_SEND)
|
||||||
Flags |= TDI_DISCONNECT_RELEASE;
|
Flags |= TDI_DISCONNECT_RELEASE;
|
||||||
if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
|
if ( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
|
||||||
DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
|
DisReq->DisconnectType & AFD_DISCONNECT_ABORT)
|
||||||
Flags |= TDI_DISCONNECT_ABORT;
|
Flags |= TDI_DISCONNECT_ABORT;
|
||||||
|
|
||||||
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
|
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
|
||||||
{
|
{
|
||||||
if( !FCB->ConnectInfo )
|
if (!FCB->ConnectInfo)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
Irp, 0 );
|
|
||||||
|
|
||||||
ASSERT(FCB->RemoteAddress);
|
ASSERT(FCB->RemoteAddress);
|
||||||
|
|
||||||
Status = TdiBuildNullConnectionInfo
|
Status = TdiBuildNullConnectionInfo
|
||||||
( &ConnectionReturnInfo, FCB->RemoteAddress->Address[0].AddressType );
|
( &ConnectionReturnInfo, FCB->RemoteAddress->Address[0].AddressType );
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if (!NT_SUCCESS(Status))
|
||||||
return UnlockAndMaybeComplete( FCB, Status,
|
return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
|
||||||
Irp, 0 );
|
|
||||||
|
|
||||||
FCB->ConnectInfo->UserData = FCB->DisconnectData;
|
FCB->ConnectInfo->UserData = FCB->DisconnectData;
|
||||||
FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
|
FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
|
||||||
|
@ -687,7 +689,9 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -698,7 +702,7 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("AfdDispatch: %d\n", IrpSp->MajorFunction));
|
AFD_DbgPrint(MID_TRACE,("AfdDispatch: %d\n", IrpSp->MajorFunction));
|
||||||
|
|
||||||
if( IrpSp->MajorFunction != IRP_MJ_CREATE)
|
if (IrpSp->MajorFunction != IRP_MJ_CREATE)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("FO %x, IrpSp->FO %x\n",
|
AFD_DbgPrint(MID_TRACE,("FO %x, IrpSp->FO %x\n",
|
||||||
FileObject, IrpSp->FileObject));
|
FileObject, IrpSp->FileObject));
|
||||||
|
@ -883,7 +887,7 @@ CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_
|
||||||
if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV ||
|
if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV ||
|
||||||
IrpSp->MajorFunction == IRP_MJ_READ)
|
IrpSp->MajorFunction == IRP_MJ_READ)
|
||||||
{
|
{
|
||||||
RecvReq = GetLockedData(Irp, IrpSp);
|
RecvReq = (PAFD_RECV_INFO)GetLockedData(Irp, IrpSp);
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
}
|
}
|
||||||
else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
|
else if ((IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
|
||||||
|
@ -895,19 +899,20 @@ CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_
|
||||||
}
|
}
|
||||||
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
|
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
|
||||||
{
|
{
|
||||||
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
PollReq = (PAFD_POLL_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||||
ZeroEvents(PollReq->Handles, PollReq->HandleCount);
|
ZeroEvents(PollReq->Handles, PollReq->HandleCount);
|
||||||
SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED);
|
SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NTAPI
|
VOID
|
||||||
|
NTAPI
|
||||||
AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
ULONG Function, IoctlCode;
|
ULONG Function, IoctlCode;
|
||||||
PIRP CurrentIrp;
|
PIRP CurrentIrp;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
@ -944,24 +949,24 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
{
|
{
|
||||||
case IOCTL_AFD_RECV:
|
case IOCTL_AFD_RECV:
|
||||||
case IOCTL_AFD_RECV_DATAGRAM:
|
case IOCTL_AFD_RECV_DATAGRAM:
|
||||||
Function = FUNCTION_RECV;
|
Function = FUNCTION_RECV;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_AFD_SEND:
|
case IOCTL_AFD_SEND:
|
||||||
case IOCTL_AFD_SEND_DATAGRAM:
|
case IOCTL_AFD_SEND_DATAGRAM:
|
||||||
Function = FUNCTION_SEND;
|
Function = FUNCTION_SEND;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_AFD_CONNECT:
|
case IOCTL_AFD_CONNECT:
|
||||||
Function = FUNCTION_CONNECT;
|
Function = FUNCTION_CONNECT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_AFD_WAIT_FOR_LISTEN:
|
case IOCTL_AFD_WAIT_FOR_LISTEN:
|
||||||
Function = FUNCTION_PREACCEPT;
|
Function = FUNCTION_PREACCEPT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_AFD_SELECT:
|
case IOCTL_AFD_SELECT:
|
||||||
KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql);
|
KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql);
|
||||||
|
|
||||||
CurrentEntry = DeviceExt->Polls.Flink;
|
CurrentEntry = DeviceExt->Polls.Flink;
|
||||||
while (CurrentEntry != &DeviceExt->Polls)
|
while (CurrentEntry != &DeviceExt->Polls)
|
||||||
|
@ -1017,12 +1022,15 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function);
|
DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
static
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
AfdUnload(PDRIVER_OBJECT DriverObject)
|
AfdUnload(PDRIVER_OBJECT DriverObject)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
@ -1039,19 +1047,18 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
|
||||||
DriverObject->DriverUnload = AfdUnload;
|
DriverObject->DriverUnload = AfdUnload;
|
||||||
|
|
||||||
Status = IoCreateDevice
|
Status = IoCreateDevice(DriverObject,
|
||||||
( DriverObject,
|
sizeof(AFD_DEVICE_EXTENSION),
|
||||||
sizeof(AFD_DEVICE_EXTENSION),
|
&wstrDeviceName,
|
||||||
&wstrDeviceName,
|
FILE_DEVICE_NAMED_PIPE,
|
||||||
FILE_DEVICE_NAMED_PIPE,
|
0,
|
||||||
0,
|
FALSE,
|
||||||
FALSE,
|
&DeviceObject );
|
||||||
&DeviceObject );
|
|
||||||
|
|
||||||
/* failure */
|
/* failure */
|
||||||
if(!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return (Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
|
|
@ -26,10 +26,9 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information )
|
static VOID HandleEOFOnIrp(PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information)
|
||||||
{
|
{
|
||||||
if( ( Status == STATUS_SUCCESS && !Information ) ||
|
if ((Status == STATUS_SUCCESS && !Information) || (!NT_SUCCESS(Status)))
|
||||||
( !NT_SUCCESS( Status ) ) )
|
|
||||||
{
|
{
|
||||||
/* The socket has been closed */
|
/* The socket has been closed */
|
||||||
FCB->PollState |= AFD_EVENT_CLOSE;
|
FCB->PollState |= AFD_EVENT_CLOSE;
|
||||||
|
@ -39,18 +38,21 @@ static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOLEAN CantReadMore( PAFD_FCB FCB ) {
|
static BOOLEAN CantReadMore( PAFD_FCB FCB )
|
||||||
|
{
|
||||||
UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
|
UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
|
||||||
|
|
||||||
return !BytesAvailable &&
|
return !BytesAvailable &&
|
||||||
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT));
|
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
|
static VOID RefillSocketBuffer( PAFD_FCB FCB )
|
||||||
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
if( !FCB->ReceiveIrp.InFlightRequest &&
|
if (!FCB->ReceiveIrp.InFlightRequest &&
|
||||||
!(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT)) ) {
|
!(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_ABORT)))
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
|
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
|
||||||
|
|
||||||
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
|
||||||
|
@ -68,9 +70,13 @@ static VOID RefillSocketBuffer( PAFD_FCB FCB ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
|
static
|
||||||
PAFD_RECV_INFO RecvReq,
|
NTSTATUS
|
||||||
PUINT TotalBytesCopied ) {
|
TryToSatisfyRecvRequestFromBuffer
|
||||||
|
( PAFD_FCB FCB,
|
||||||
|
PAFD_RECV_INFO RecvReq,
|
||||||
|
PUINT TotalBytesCopied )
|
||||||
|
{
|
||||||
UINT i, BytesToCopy = 0, FcbBytesCopied = FCB->Recv.BytesUsed,
|
UINT i, BytesToCopy = 0, FcbBytesCopied = FCB->Recv.BytesUsed,
|
||||||
BytesAvailable =
|
BytesAvailable =
|
||||||
FCB->Recv.Content - FCB->Recv.BytesUsed;
|
FCB->Recv.Content - FCB->Recv.BytesUsed;
|
||||||
|
@ -81,23 +87,24 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
|
||||||
AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n",
|
AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n",
|
||||||
BytesAvailable));
|
BytesAvailable));
|
||||||
|
|
||||||
if( CantReadMore(FCB) ) return STATUS_SUCCESS;
|
if (CantReadMore(FCB))
|
||||||
if( !BytesAvailable ) return STATUS_PENDING;
|
return STATUS_SUCCESS;
|
||||||
|
if (!BytesAvailable)
|
||||||
|
return STATUS_PENDING;
|
||||||
|
|
||||||
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
|
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Buffer Count: %d @ %x\n",
|
AFD_DbgPrint(MID_TRACE,("Buffer Count: %d @ %x\n",
|
||||||
RecvReq->BufferCount,
|
RecvReq->BufferCount,
|
||||||
RecvReq->BufferArray));
|
RecvReq->BufferArray));
|
||||||
for( i = 0;
|
for (i = 0;
|
||||||
RecvReq->BufferArray &&
|
RecvReq->BufferArray && BytesAvailable && i < RecvReq->BufferCount;
|
||||||
BytesAvailable &&
|
i++)
|
||||||
i < RecvReq->BufferCount;
|
{
|
||||||
i++ ) {
|
BytesToCopy = MIN(RecvReq->BufferArray[i].len, BytesAvailable);
|
||||||
BytesToCopy =
|
|
||||||
MIN( RecvReq->BufferArray[i].len, BytesAvailable );
|
|
||||||
|
|
||||||
if( Map[i].Mdl ) {
|
if (Map[i].Mdl)
|
||||||
|
{
|
||||||
Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode );
|
Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode );
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
|
AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n",
|
||||||
|
@ -121,7 +128,8 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there's nothing left in our buffer start a new request */
|
/* If there's nothing left in our buffer start a new request */
|
||||||
if( FCB->Recv.BytesUsed == FCB->Recv.Content ) {
|
if ( FCB->Recv.BytesUsed == FCB->Recv.Content )
|
||||||
|
{
|
||||||
FCB->Recv.BytesUsed = FCB->Recv.Content = 0;
|
FCB->Recv.BytesUsed = FCB->Recv.Content = 0;
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
|
|
||||||
|
@ -131,7 +139,10 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
|
static
|
||||||
|
NTSTATUS
|
||||||
|
ReceiveActivity(PAFD_FCB FCB, PIRP Irp)
|
||||||
|
{
|
||||||
PLIST_ENTRY NextIrpEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
PIRP NextIrp;
|
PIRP NextIrp;
|
||||||
PIO_STACK_LOCATION NextIrpSp;
|
PIO_STACK_LOCATION NextIrpSp;
|
||||||
|
@ -147,32 +158,38 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
|
||||||
AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n",
|
AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n",
|
||||||
FCB, FCB->Recv.Content));
|
FCB, FCB->Recv.Content));
|
||||||
|
|
||||||
if( CantReadMore( FCB ) ) {
|
if (CantReadMore(FCB))
|
||||||
|
{
|
||||||
/* Success here means that we got an EOF. Complete a pending read
|
/* Success here means that we got an EOF. Complete a pending read
|
||||||
* with zero bytes if we haven't yet overread, then kill the others.
|
* with zero bytes if we haven't yet overread, then kill the others.
|
||||||
*/
|
*/
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV]))
|
||||||
NextIrpEntry =
|
{
|
||||||
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
||||||
NextIrp =
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
|
||||||
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
|
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
|
||||||
TotalBytesCopied));
|
TotalBytesCopied));
|
||||||
UnlockBuffers( RecvReq->BufferArray,
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
RecvReq->BufferCount, FALSE );
|
|
||||||
Status = NextIrp->IoStatus.Status =
|
Status = NextIrp->IoStatus.Status =
|
||||||
FCB->Overread ? STATUS_END_OF_FILE : STATUS_SUCCESS;
|
FCB->Overread ? STATUS_END_OF_FILE : STATUS_SUCCESS;
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Information = 0;
|
||||||
if( NextIrp == Irp ) RetStatus = Status;
|
|
||||||
if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
if (NextIrp == Irp)
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
RetStatus = Status;
|
||||||
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
FCB->Overread = TRUE;
|
FCB->Overread = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Kick the user that receive would be possible now */
|
/* Kick the user that receive would be possible now */
|
||||||
/* XXX Not implemented yet */
|
/* XXX Not implemented yet */
|
||||||
|
|
||||||
|
@ -181,54 +198,62 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
|
||||||
/*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/
|
/*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/
|
||||||
|
|
||||||
/* Try to clear some requests */
|
/* Try to clear some requests */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV]))
|
||||||
NextIrpEntry =
|
{
|
||||||
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
||||||
NextIrp =
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
|
||||||
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq));
|
AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq));
|
||||||
|
|
||||||
Status = TryToSatisfyRecvRequestFromBuffer
|
Status = TryToSatisfyRecvRequestFromBuffer(FCB, RecvReq, &TotalBytesCopied);
|
||||||
( FCB, RecvReq, &TotalBytesCopied );
|
|
||||||
|
|
||||||
if( Status == STATUS_PENDING ) {
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Ran out of data for %x\n", NextIrp));
|
AFD_DbgPrint(MID_TRACE,("Ran out of data for %x\n", NextIrp));
|
||||||
InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV],
|
InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV],
|
||||||
&NextIrp->Tail.Overlay.ListEntry);
|
&NextIrp->Tail.Overlay.ListEntry);
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
|
AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
|
||||||
TotalBytesCopied));
|
TotalBytesCopied));
|
||||||
UnlockBuffers( RecvReq->BufferArray,
|
UnlockBuffers( RecvReq->BufferArray,
|
||||||
RecvReq->BufferCount, FALSE );
|
RecvReq->BufferCount, FALSE );
|
||||||
NextIrp->IoStatus.Status = Status;
|
NextIrp->IoStatus.Status = Status;
|
||||||
NextIrp->IoStatus.Information = TotalBytesCopied;
|
NextIrp->IoStatus.Information = TotalBytesCopied;
|
||||||
if( NextIrp == Irp ) {
|
|
||||||
|
if (NextIrp == Irp)
|
||||||
|
{
|
||||||
RetStatus = Status;
|
RetStatus = Status;
|
||||||
RetBytesCopied = TotalBytesCopied;
|
RetBytesCopied = TotalBytesCopied;
|
||||||
}
|
}
|
||||||
if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
if (NextIrp->MdlAddress)
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FCB->Recv.Content - FCB->Recv.BytesUsed &&
|
if( FCB->Recv.Content - FCB->Recv.BytesUsed &&
|
||||||
IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
|
IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) )
|
||||||
|
{
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus));
|
AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus));
|
||||||
|
|
||||||
/* Sometimes we're called with a NULL Irp */
|
/* Sometimes we're called with a NULL Irp */
|
||||||
if( Irp ) {
|
if (Irp)
|
||||||
|
{
|
||||||
Irp->IoStatus.Status = RetStatus;
|
Irp->IoStatus.Status = RetStatus;
|
||||||
Irp->IoStatus.Information = RetBytesCopied;
|
Irp->IoStatus.Information = RetBytesCopied;
|
||||||
}
|
}
|
||||||
|
@ -236,10 +261,13 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
|
||||||
return RetStatus;
|
return RetStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI ReceiveComplete
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ReceiveComplete
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
PVOID Context ) {
|
PVOID Context )
|
||||||
|
{
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PLIST_ENTRY NextIrpEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
PIRP NextIrp;
|
PIRP NextIrp;
|
||||||
|
@ -248,7 +276,7 @@ NTSTATUS NTAPI ReceiveComplete
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
|
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
|
||||||
|
@ -257,24 +285,33 @@ NTSTATUS NTAPI ReceiveComplete
|
||||||
FCB->Recv.Content = Irp->IoStatus.Information;
|
FCB->Recv.Content = Irp->IoStatus.Information;
|
||||||
FCB->Recv.BytesUsed = 0;
|
FCB->Recv.BytesUsed = 0;
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if (FCB->State == SOCKET_STATE_CLOSED)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MIN_TRACE,("!!! CLOSING SOCK GOT A RECEIVE COMPLETE !!!\n"));
|
AFD_DbgPrint(MIN_TRACE,("!!! CLOSING SOCK GOT A RECEIVE COMPLETE !!!\n"));
|
||||||
|
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV]))
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
{
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
NextIrp->IoStatus.Information = 0;
|
||||||
if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
SocketStateUnlock( FCB );
|
|
||||||
return STATUS_FILE_CLOSED;
|
SocketStateUnlock( FCB );
|
||||||
} else if( FCB->State == SOCKET_STATE_LISTENING ) {
|
return STATUS_FILE_CLOSED;
|
||||||
|
}
|
||||||
|
else if (FCB->State == SOCKET_STATE_LISTENING)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
|
AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock( FCB );
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
@ -289,37 +326,41 @@ NTSTATUS NTAPI ReceiveComplete
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp, BOOLEAN Short) {
|
AfdConnectedSocketReadData
|
||||||
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp,
|
||||||
|
BOOLEAN Short )
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_RECV_INFO RecvReq;
|
PAFD_RECV_INFO RecvReq;
|
||||||
UINT TotalBytesCopied = 0;
|
UINT TotalBytesCopied = 0;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if( FCB->State != SOCKET_STATE_CONNECTED &&
|
if (FCB->State != SOCKET_STATE_CONNECTED && FCB->State != SOCKET_STATE_CONNECTING)
|
||||||
FCB->State != SOCKET_STATE_CONNECTING ) {
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Called recv on wrong kind of socket (s%x)\n",
|
AFD_DbgPrint(MID_TRACE,("Called recv on wrong kind of socket (s%x)\n",
|
||||||
FCB->State));
|
FCB->State));
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
|
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
|
||||||
Irp, 0 );
|
Irp, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
|
if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
|
||||||
{
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Receive on connection-less sockets not implemented\n"));
|
AFD_DbgPrint(MID_TRACE,("Receive on connection-less sockets not implemented\n"));
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NOT_IMPLEMENTED,
|
return UnlockAndMaybeComplete(FCB, STATUS_NOT_IMPLEMENTED, Irp, 0);
|
||||||
Irp, 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
|
if (!(RecvReq = LockRequest(Irp, IrpSp)))
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
Irp, 0 );
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
|
AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
|
||||||
|
|
||||||
|
@ -328,9 +369,9 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
TRUE, FALSE );
|
TRUE, FALSE );
|
||||||
|
|
||||||
if( !RecvReq->BufferArray ) {
|
if (!RecvReq->BufferArray)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
|
{
|
||||||
Irp, 0 );
|
return UnlockAndMaybeComplete(FCB, STATUS_ACCESS_VIOLATION, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
Irp->IoStatus.Status = STATUS_PENDING;
|
||||||
|
@ -343,19 +384,23 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
Status = ReceiveActivity( FCB, Irp );
|
Status = ReceiveActivity( FCB, Irp );
|
||||||
|
|
||||||
if( Status == STATUS_PENDING && (RecvReq->AfdFlags & AFD_IMMEDIATE) ) {
|
if (Status == STATUS_PENDING && (RecvReq->AfdFlags & AFD_IMMEDIATE))
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||||
Status = STATUS_CANT_WAIT;
|
Status = STATUS_CANT_WAIT;
|
||||||
TotalBytesCopied = 0;
|
TotalBytesCopied = 0;
|
||||||
RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
|
RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
|
||||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp,
|
return UnlockAndMaybeComplete( FCB, Status, Irp, TotalBytesCopied);
|
||||||
TotalBytesCopied );
|
}
|
||||||
} else if( Status == STATUS_PENDING ) {
|
else if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
|
AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
|
||||||
IoMarkIrpPending( Irp );
|
IoMarkIrpPending( Irp );
|
||||||
(void)IoSetCancelRoutine(Irp, AfdCancelHandler);
|
(void)IoSetCancelRoutine(Irp, AfdCancelHandler);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,14 +409,17 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS NTAPI
|
static
|
||||||
SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
|
NTSTATUS
|
||||||
PAFD_STORED_DATAGRAM DatagramRecv,
|
NTAPI
|
||||||
PUINT TotalBytesCopied ) {
|
SatisfyPacketRecvRequest
|
||||||
|
( PAFD_FCB FCB, PIRP Irp,
|
||||||
|
PAFD_STORED_DATAGRAM DatagramRecv,
|
||||||
|
PUINT TotalBytesCopied )
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PAFD_RECV_INFO RecvReq =
|
PAFD_RECV_INFO RecvReq = (PAFD_RECV_INFO)GetLockedData(Irp, IrpSp);
|
||||||
GetLockedData(Irp, IrpSp);
|
|
||||||
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
|
UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0;
|
||||||
PAFD_MAPBUF Map;
|
PAFD_MAPBUF Map;
|
||||||
|
|
||||||
|
@ -379,18 +427,20 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
|
||||||
RecvReq->BufferCount +
|
RecvReq->BufferCount +
|
||||||
EXTRA_LOCK_BUFFERS);
|
EXTRA_LOCK_BUFFERS);
|
||||||
|
|
||||||
BytesToCopy =
|
BytesToCopy = MIN(RecvReq->BufferArray[0].len, BytesAvailable);
|
||||||
MIN( RecvReq->BufferArray[0].len, BytesAvailable );
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
|
AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy,
|
||||||
RecvReq->BufferArray[0].len));
|
RecvReq->BufferArray[0].len));
|
||||||
|
|
||||||
if( Map[0].Mdl ) {
|
if (Map[0].Mdl)
|
||||||
|
{
|
||||||
/* Copy the address */
|
/* Copy the address */
|
||||||
if( Map[1].Mdl && Map[2].Mdl ) {
|
if (Map[1].Mdl && Map[2].Mdl)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
|
AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n"));
|
||||||
|
|
||||||
if( DatagramRecv->Address->TAAddressCount != 1 ) {
|
if (DatagramRecv->Address->TAAddressCount != 1)
|
||||||
|
{
|
||||||
AFD_DbgPrint
|
AFD_DbgPrint
|
||||||
(MID_TRACE,
|
(MID_TRACE,
|
||||||
("Wierd address count %d\n",
|
("Wierd address count %d\n",
|
||||||
|
@ -454,13 +504,15 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
PacketSocketRecvComplete(
|
NTAPI
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PacketSocketRecvComplete
|
||||||
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
PVOID Context ) {
|
PVOID Context )
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAFD_FCB FCB = Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PIRP NextIrp;
|
PIRP NextIrp;
|
||||||
PIO_STACK_LOCATION NextIrpSp;
|
PIO_STACK_LOCATION NextIrpSp;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
|
@ -471,37 +523,43 @@ PacketSocketRecvComplete(
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
|
ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
|
||||||
FCB->ReceiveIrp.InFlightRequest = NULL;
|
FCB->ReceiveIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if ( FCB->State == SOCKET_STATE_CLOSED )
|
||||||
|
{
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
|
while ( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV]))
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
{
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
RecvReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
NextIrp->IoStatus.Information = 0;
|
||||||
if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation(NextIrp));
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free all items on the datagram list */
|
/* Free all items on the datagram list */
|
||||||
while( !IsListEmpty( &FCB->DatagramList ) ) {
|
while (!IsListEmpty(&FCB->DatagramList))
|
||||||
DatagramRecvEntry = RemoveHeadList(&FCB->DatagramList);
|
{
|
||||||
DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry);
|
DatagramRecvEntry = RemoveHeadList(&FCB->DatagramList);
|
||||||
ExFreePool( DatagramRecv->Address );
|
DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry);
|
||||||
ExFreePool( DatagramRecv );
|
ExFreePool( DatagramRecv->Address );
|
||||||
|
ExFreePool( DatagramRecv );
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock(FCB);
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Irp->IoStatus.Status != STATUS_SUCCESS)
|
if (Irp->IoStatus.Status != STATUS_SUCCESS)
|
||||||
|
@ -512,7 +570,8 @@ PacketSocketRecvComplete(
|
||||||
|
|
||||||
DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
|
DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );
|
||||||
|
|
||||||
if( DatagramRecv ) {
|
if (DatagramRecv)
|
||||||
|
{
|
||||||
DatagramRecv->Len = Irp->IoStatus.Information;
|
DatagramRecv->Len = Irp->IoStatus.Information;
|
||||||
RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
|
RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
|
||||||
DatagramRecv->Len );
|
DatagramRecv->Len );
|
||||||
|
@ -521,22 +580,29 @@ PacketSocketRecvComplete(
|
||||||
DatagramRecv->Address =
|
DatagramRecv->Address =
|
||||||
TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );
|
TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );
|
||||||
|
|
||||||
if( !DatagramRecv->Address ) Status = STATUS_NO_MEMORY;
|
if (!DatagramRecv->Address)
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
|
||||||
} else Status = STATUS_NO_MEMORY;
|
}
|
||||||
|
else Status = STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if( !NT_SUCCESS( Status ) ) {
|
if (!NT_SUCCESS(Status))
|
||||||
if( DatagramRecv ) ExFreePool( DatagramRecv );
|
{
|
||||||
SocketStateUnlock( FCB );
|
if (DatagramRecv)
|
||||||
|
ExFreePool(DatagramRecv);
|
||||||
|
SocketStateUnlock(FCB);
|
||||||
return Status;
|
return Status;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
|
InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Satisfy as many requests as we can */
|
/* Satisfy as many requests as we can */
|
||||||
|
|
||||||
while( !IsListEmpty( &FCB->DatagramList ) &&
|
while( !IsListEmpty( &FCB->DatagramList ) &&
|
||||||
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
|
!IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) )
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
|
AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
|
||||||
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
||||||
DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
|
DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
|
||||||
|
@ -549,8 +615,9 @@ PacketSocketRecvComplete(
|
||||||
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
|
AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n",
|
||||||
RecvReq, DatagramRecv));
|
RecvReq, DatagramRecv));
|
||||||
|
|
||||||
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
if (DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
||||||
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
|
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL))
|
||||||
|
{
|
||||||
InsertHeadList( &FCB->DatagramList,
|
InsertHeadList( &FCB->DatagramList,
|
||||||
&DatagramRecv->ListEntry );
|
&DatagramRecv->ListEntry );
|
||||||
Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
Status = NextIrp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
@ -559,7 +626,9 @@ PacketSocketRecvComplete(
|
||||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
|
AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
|
||||||
Status = SatisfyPacketRecvRequest
|
Status = SatisfyPacketRecvRequest
|
||||||
( FCB, NextIrp, DatagramRecv,
|
( FCB, NextIrp, DatagramRecv,
|
||||||
|
@ -569,24 +638,30 @@ PacketSocketRecvComplete(
|
||||||
InsertHeadList(&FCB->DatagramList,
|
InsertHeadList(&FCB->DatagramList,
|
||||||
&DatagramRecv->ListEntry);
|
&DatagramRecv->ListEntry);
|
||||||
}
|
}
|
||||||
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
|
||||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
|
||||||
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->DatagramList ) && IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
|
if (!IsListEmpty( &FCB->DatagramList ) && IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]))
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
|
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
|
|
||||||
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
|
if (NT_SUCCESS(Irp->IoStatus.Status))
|
||||||
|
{
|
||||||
/* Now relaunch the datagram request */
|
/* Now relaunch the datagram request */
|
||||||
Status = TdiReceiveDatagram
|
Status = TdiReceiveDatagram
|
||||||
( &FCB->ReceiveIrp.InFlightRequest,
|
( &FCB->ReceiveIrp.InFlightRequest,
|
||||||
|
@ -605,27 +680,31 @@ PacketSocketRecvComplete(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdPacketSocketReadData
|
||||||
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp )
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_RECV_INFO_UDP RecvReq;
|
PAFD_RECV_INFO_UDP RecvReq;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PAFD_STORED_DATAGRAM DatagramRecv;
|
PAFD_STORED_DATAGRAM DatagramRecv;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
/* Check that the socket is bound */
|
/* Check that the socket is bound */
|
||||||
if( FCB->State != SOCKET_STATE_BOUND )
|
if (FCB->State != SOCKET_STATE_BOUND)
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
||||||
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
|
if ( !(RecvReq = LockRequest(Irp, IrpSp)))
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
|
AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
|
||||||
|
|
||||||
|
@ -635,37 +714,42 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
RecvReq->AddressLength,
|
RecvReq->AddressLength,
|
||||||
TRUE, TRUE );
|
TRUE, TRUE );
|
||||||
|
|
||||||
if( !RecvReq->BufferArray ) { /* access violation in userspace */
|
if (!RecvReq->BufferArray)
|
||||||
return UnlockAndMaybeComplete
|
{
|
||||||
( FCB, STATUS_ACCESS_VIOLATION, Irp, 0 );
|
/* access violation in userspace */
|
||||||
|
return UnlockAndMaybeComplete(FCB, STATUS_ACCESS_VIOLATION, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
if ( !IsListEmpty(&FCB->DatagramList))
|
||||||
|
{
|
||||||
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
ListEntry = RemoveHeadList( &FCB->DatagramList );
|
||||||
DatagramRecv = CONTAINING_RECORD
|
DatagramRecv = CONTAINING_RECORD(ListEntry, AFD_STORED_DATAGRAM, ListEntry);
|
||||||
( ListEntry, AFD_STORED_DATAGRAM, ListEntry );
|
|
||||||
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
if( DatagramRecv->Len > RecvReq->BufferArray[0].len &&
|
||||||
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) ) {
|
!(RecvReq->TdiFlags & TDI_RECEIVE_PARTIAL) )
|
||||||
|
{
|
||||||
InsertHeadList( &FCB->DatagramList,
|
InsertHeadList( &FCB->DatagramList,
|
||||||
&DatagramRecv->ListEntry );
|
&DatagramRecv->ListEntry );
|
||||||
Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
Status = Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
Irp->IoStatus.Information = DatagramRecv->Len;
|
Irp->IoStatus.Information = DatagramRecv->Len;
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
if ( !IsListEmpty(&FCB->DatagramList))
|
||||||
|
{
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
|
|
||||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||||
|
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
|
||||||
( FCB, Status, Irp, Irp->IoStatus.Information );
|
}
|
||||||
} else {
|
else
|
||||||
Status = SatisfyPacketRecvRequest
|
{
|
||||||
( FCB, Irp, DatagramRecv,
|
Status = SatisfyPacketRecvRequest(
|
||||||
(PUINT)&Irp->IoStatus.Information );
|
FCB, Irp, DatagramRecv,
|
||||||
|
(PUINT)&Irp->IoStatus.Information);
|
||||||
|
|
||||||
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
|
if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
|
||||||
{
|
{
|
||||||
|
@ -673,25 +757,31 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
&DatagramRecv->ListEntry);
|
&DatagramRecv->ListEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !IsListEmpty( &FCB->DatagramList ) ) {
|
if (!IsListEmpty(&FCB->DatagramList))
|
||||||
|
{
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||||
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
|
|
||||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
||||||
|
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information);
|
||||||
( FCB, Status, Irp, Irp->IoStatus.Information );
|
|
||||||
}
|
}
|
||||||
} else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
|
}
|
||||||
|
else if (RecvReq->AfdFlags & AFD_IMMEDIATE)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||||
Status = STATUS_CANT_WAIT;
|
Status = STATUS_CANT_WAIT;
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, TRUE );
|
|
||||||
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, TRUE);
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static VOID PrintEvents( ULONG Events ) {
|
static VOID PrintEvents(ULONG Events)
|
||||||
|
{
|
||||||
#if DBG
|
#if DBG
|
||||||
char *events_list[] = { "AFD_EVENT_RECEIVE",
|
char *events_list[] = { "AFD_EVENT_RECEIVE",
|
||||||
"AFD_EVENT_OOB_RECEIVE",
|
"AFD_EVENT_OOB_RECEIVE",
|
||||||
|
@ -33,34 +34,35 @@ static VOID PrintEvents( ULONG Events ) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID CopyBackStatus( PAFD_HANDLE HandleArray,
|
static VOID CopyBackStatus(PAFD_HANDLE HandleArray, UINT HandleCount)
|
||||||
UINT HandleCount ) {
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
for( i = 0; i < HandleCount; i++ ) {
|
for (i = 0; i<HandleCount; i++)
|
||||||
HandleArray[i].Events = HandleArray[i].Status;
|
{
|
||||||
HandleArray[i].Status = 0;
|
HandleArray[i].Events = HandleArray[i].Status;
|
||||||
|
HandleArray[i].Status = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID ZeroEvents( PAFD_HANDLE HandleArray,
|
VOID ZeroEvents(PAFD_HANDLE HandleArray, UINT HandleCount)
|
||||||
UINT HandleCount ) {
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
for( i = 0; i < HandleCount; i++ ) {
|
for (i = 0; i<HandleCount; i++)
|
||||||
HandleArray[i].Status = 0;
|
{
|
||||||
HandleArray[i].Events = 0;
|
HandleArray[i].Status = 0;
|
||||||
|
HandleArray[i].Events = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* you must pass either Poll OR Irp */
|
/* you must pass either Poll OR Irp */
|
||||||
VOID SignalSocket(
|
VOID SignalSocket
|
||||||
PAFD_ACTIVE_POLL Poll OPTIONAL,
|
( PAFD_ACTIVE_POLL Poll OPTIONAL,
|
||||||
PIRP _Irp OPTIONAL,
|
PIRP _Irp OPTIONAL,
|
||||||
PAFD_POLL_INFO PollReq,
|
PAFD_POLL_INFO PollReq,
|
||||||
NTSTATUS Status
|
NTSTATUS Status )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
PIRP Irp = _Irp ? _Irp : Poll->Irp;
|
PIRP Irp = _Irp ? _Irp : Poll->Irp;
|
||||||
|
@ -68,17 +70,18 @@ VOID SignalSocket(
|
||||||
|
|
||||||
if (Poll)
|
if (Poll)
|
||||||
{
|
{
|
||||||
KeCancelTimer( &Poll->Timer );
|
KeCancelTimer( &Poll->Timer );
|
||||||
RemoveEntryList( &Poll->ListEntry );
|
RemoveEntryList( &Poll->ListEntry );
|
||||||
ExFreePool( Poll );
|
ExFreePool( Poll );
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information =
|
Irp->IoStatus.Information =
|
||||||
FIELD_OFFSET(AFD_POLL_INFO, Handles) + sizeof(AFD_HANDLE) * PollReq->HandleCount;
|
FIELD_OFFSET(AFD_POLL_INFO, Handles) + sizeof(AFD_HANDLE) * PollReq->HandleCount;
|
||||||
CopyBackStatus( PollReq->Handles,
|
|
||||||
PollReq->HandleCount );
|
CopyBackStatus( PollReq->Handles, PollReq->HandleCount);
|
||||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
for (i=0; i < PollReq->HandleCount; i++)
|
||||||
|
{
|
||||||
AFD_DbgPrint
|
AFD_DbgPrint
|
||||||
(MAX_TRACE,
|
(MAX_TRACE,
|
||||||
("Handle(%x): Got %x,%x\n",
|
("Handle(%x): Got %x,%x\n",
|
||||||
|
@ -86,19 +89,25 @@ VOID SignalSocket(
|
||||||
PollReq->Handles[i].Events,
|
PollReq->Handles[i].Events,
|
||||||
PollReq->Handles[i].Status));
|
PollReq->Handles[i].Status));
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
|
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
|
||||||
if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
|
if (Irp->MdlAddress)
|
||||||
|
UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
||||||
|
|
||||||
(void)IoSetCancelRoutine(Irp, NULL);
|
(void)IoSetCancelRoutine(Irp, NULL);
|
||||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID SelectTimeout( PKDPC Dpc,
|
static VOID SelectTimeout( PKDPC Dpc,
|
||||||
PVOID DeferredContext,
|
PVOID DeferredContext,
|
||||||
PVOID SystemArgument1,
|
PVOID SystemArgument1,
|
||||||
PVOID SystemArgument2 ) {
|
PVOID SystemArgument2 )
|
||||||
PAFD_ACTIVE_POLL Poll = DeferredContext;
|
{
|
||||||
|
PAFD_ACTIVE_POLL Poll = (PAFD_ACTIVE_POLL)DeferredContext;
|
||||||
PAFD_POLL_INFO PollReq;
|
PAFD_POLL_INFO PollReq;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
@ -121,7 +130,8 @@ static VOID SelectTimeout( PKDPC Dpc,
|
||||||
|
|
||||||
VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
|
VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_OBJECT FileObject,
|
PFILE_OBJECT FileObject,
|
||||||
BOOLEAN OnlyExclusive ) {
|
BOOLEAN OnlyExclusive )
|
||||||
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PAFD_ACTIVE_POLL Poll;
|
PAFD_ACTIVE_POLL Poll;
|
||||||
|
@ -135,22 +145,26 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
|
||||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||||
|
|
||||||
ListEntry = DeviceExt->Polls.Flink;
|
ListEntry = DeviceExt->Polls.Flink;
|
||||||
while ( ListEntry != &DeviceExt->Polls ) {
|
while (ListEntry != &DeviceExt->Polls)
|
||||||
Poll = CONTAINING_RECORD(ListEntry, AFD_ACTIVE_POLL, ListEntry);
|
{
|
||||||
ListEntry = ListEntry->Flink;
|
Poll = CONTAINING_RECORD(ListEntry, AFD_ACTIVE_POLL, ListEntry);
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
Irp = Poll->Irp;
|
Irp = Poll->Irp;
|
||||||
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||||
HandleArray = AFD_HANDLES(PollReq);
|
HandleArray = AFD_HANDLES(PollReq);
|
||||||
|
|
||||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
for (i = 0; i < PollReq->HandleCount; i++)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MAX_TRACE,("Req: %x, This %x\n",
|
AFD_DbgPrint(MAX_TRACE,("Req: %x, This %x\n",
|
||||||
HandleArray[i].Handle, FileObject));
|
HandleArray[i].Handle, FileObject));
|
||||||
if( (PVOID)HandleArray[i].Handle == FileObject &&
|
|
||||||
(!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) {
|
if ((PVOID)HandleArray[i].Handle == FileObject &&
|
||||||
|
(!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) )
|
||||||
|
{
|
||||||
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
||||||
SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED );
|
SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
|
@ -158,17 +172,17 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
|
||||||
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_NO_MEMORY;
|
NTSTATUS Status = STATUS_NO_MEMORY;
|
||||||
PAFD_FCB FCB;
|
PAFD_FCB FCB;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer;
|
PAFD_POLL_INFO PollReq = (PAFD_POLL_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||||
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
UINT CopySize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
UINT CopySize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
UINT AllocSize =
|
UINT AllocSize = CopySize + sizeof(AFD_ACTIVE_POLL) - sizeof(AFD_POLL_INFO);
|
||||||
CopySize + sizeof(AFD_ACTIVE_POLL) - sizeof(AFD_POLL_INFO);
|
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
UINT i, Signalled = 0;
|
UINT i, Signalled = 0;
|
||||||
ULONG Exclusive = PollReq->Exclusive;
|
ULONG Exclusive = PollReq->Exclusive;
|
||||||
|
@ -180,18 +194,22 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
SET_AFD_HANDLES(PollReq,
|
SET_AFD_HANDLES(PollReq,
|
||||||
LockHandles( PollReq->Handles, PollReq->HandleCount ));
|
LockHandles( PollReq->Handles, PollReq->HandleCount ));
|
||||||
|
|
||||||
if( !AFD_HANDLES(PollReq) ) {
|
if (!AFD_HANDLES(PollReq))
|
||||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
{
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
Irp->IoStatus.Information = 0;
|
||||||
return STATUS_NO_MEMORY;
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Exclusive ) {
|
if (Exclusive)
|
||||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
{
|
||||||
if( !AFD_HANDLES(PollReq)[i].Handle ) continue;
|
for (i = 0; i<PollReq->HandleCount; i++)
|
||||||
|
{
|
||||||
|
if (!AFD_HANDLES(PollReq)[i].Handle)
|
||||||
|
continue;
|
||||||
|
|
||||||
KillSelectsForFCB( DeviceExt,
|
KillSelectsForFCB(DeviceExt,
|
||||||
(PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle,
|
(PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle,
|
||||||
TRUE );
|
TRUE );
|
||||||
}
|
}
|
||||||
|
@ -199,8 +217,10 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||||
|
|
||||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
for (i=0; i<PollReq->HandleCount; i++)
|
||||||
if( !AFD_HANDLES(PollReq)[i].Handle ) continue;
|
{
|
||||||
|
if (!AFD_HANDLES(PollReq)[i].Handle)
|
||||||
|
continue;
|
||||||
|
|
||||||
FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle;
|
FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle;
|
||||||
FCB = FileObject->FsContext;
|
FCB = FileObject->FsContext;
|
||||||
|
@ -209,47 +229,52 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PrintEvents( PollReq->Handles[i].Events );
|
PrintEvents( PollReq->Handles[i].Events );
|
||||||
AFD_DbgPrint(MID_TRACE,("\n"));
|
AFD_DbgPrint(MID_TRACE,("\n"));
|
||||||
|
|
||||||
PollReq->Handles[i].Status =
|
PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState;
|
||||||
PollReq->Handles[i].Events & FCB->PollState;
|
if (PollReq->Handles[i].Status)
|
||||||
if( PollReq->Handles[i].Status ) {
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n",
|
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n",
|
||||||
FCB, FCB->PollState));
|
FCB, FCB->PollState));
|
||||||
Signalled++;
|
Signalled++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Signalled ) {
|
if (Signalled)
|
||||||
|
{
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
SignalSocket( NULL, Irp, PollReq, Status );
|
SignalSocket( NULL, Irp, PollReq, Status );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PAFD_ACTIVE_POLL Poll = NULL;
|
||||||
|
|
||||||
PAFD_ACTIVE_POLL Poll = NULL;
|
Poll = ExAllocatePool( NonPagedPool, AllocSize );
|
||||||
|
|
||||||
Poll = ExAllocatePool( NonPagedPool, AllocSize );
|
if (Poll)
|
||||||
|
{
|
||||||
|
Poll->Irp = Irp;
|
||||||
|
Poll->DeviceExt = DeviceExt;
|
||||||
|
Poll->Exclusive = Exclusive;
|
||||||
|
|
||||||
if (Poll){
|
KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
|
||||||
Poll->Irp = Irp;
|
|
||||||
Poll->DeviceExt = DeviceExt;
|
|
||||||
Poll->Exclusive = Exclusive;
|
|
||||||
|
|
||||||
KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
|
KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
|
||||||
|
(PKDEFERRED_ROUTINE)SelectTimeout,
|
||||||
|
Poll );
|
||||||
|
|
||||||
KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
|
InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
|
||||||
(PKDEFERRED_ROUTINE)SelectTimeout,
|
|
||||||
Poll );
|
|
||||||
|
|
||||||
InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
|
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
|
||||||
|
|
||||||
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
|
Status = STATUS_PENDING;
|
||||||
|
IoMarkIrpPending( Irp );
|
||||||
Status = STATUS_PENDING;
|
(void)IoSetCancelRoutine(Irp, AfdCancelHandler);
|
||||||
IoMarkIrpPending( Irp );
|
}
|
||||||
(void)IoSetCancelRoutine(Irp, AfdCancelHandler);
|
else
|
||||||
} else {
|
{
|
||||||
AFD_DbgPrint(MAX_TRACE, ("FIXME: do something with the IRP!\n"));
|
AFD_DbgPrint(MAX_TRACE, ("FIXME: do something with the IRP!\n"));
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
|
@ -259,72 +284,80 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdEventSelect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
NTSTATUS Status = STATUS_NO_MEMORY;
|
NTSTATUS Status = STATUS_NO_MEMORY;
|
||||||
PAFD_EVENT_SELECT_INFO EventSelectInfo =
|
PAFD_EVENT_SELECT_INFO EventSelectInfo =
|
||||||
(PAFD_EVENT_SELECT_INFO)LockRequest( Irp, IrpSp );
|
(PAFD_EVENT_SELECT_INFO)LockRequest( Irp, IrpSp );
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) {
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return LostSocket( Irp );
|
{
|
||||||
|
return LostSocket(Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !EventSelectInfo ) {
|
if (!EventSelectInfo)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
|
{
|
||||||
0 );
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called (Event %x Triggers %x)\n",
|
AFD_DbgPrint(MID_TRACE,("Called (Event %x Triggers %x)\n",
|
||||||
EventSelectInfo->EventObject,
|
EventSelectInfo->EventObject,
|
||||||
EventSelectInfo->Events));
|
EventSelectInfo->Events));
|
||||||
|
|
||||||
if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect );
|
if (FCB->EventSelect)
|
||||||
|
ObDereferenceObject(FCB->EventSelect);
|
||||||
FCB->EventSelect = NULL;
|
FCB->EventSelect = NULL;
|
||||||
|
|
||||||
if( EventSelectInfo->EventObject && EventSelectInfo->Events ) {
|
if (EventSelectInfo->EventObject && EventSelectInfo->Events)
|
||||||
Status = ObReferenceObjectByHandle( (PVOID)EventSelectInfo->
|
{
|
||||||
EventObject,
|
Status = ObReferenceObjectByHandle(
|
||||||
FILE_ALL_ACCESS,
|
(PVOID)EventSelectInfo->EventObject,
|
||||||
ExEventObjectType,
|
FILE_ALL_ACCESS,
|
||||||
UserMode,
|
ExEventObjectType,
|
||||||
(PVOID *)&FCB->EventSelect,
|
UserMode,
|
||||||
NULL );
|
(PVOID *)&FCB->EventSelect,
|
||||||
|
NULL );
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) )
|
if( !NT_SUCCESS(Status) )
|
||||||
FCB->EventSelect = NULL;
|
FCB->EventSelect = NULL;
|
||||||
else
|
else
|
||||||
FCB->EventSelectTriggers = EventSelectInfo->Events;
|
FCB->EventSelectTriggers = EventSelectInfo->Events;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FCB->EventSelect = NULL;
|
FCB->EventSelect = NULL;
|
||||||
FCB->EventSelectTriggers = 0;
|
FCB->EventSelectTriggers = 0;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||||
|
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp,
|
return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
|
||||||
0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
AfdEnumEvents(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_ENUM_NETWORK_EVENTS_INFO EnumReq =
|
PAFD_ENUM_NETWORK_EVENTS_INFO EnumReq =
|
||||||
(PAFD_ENUM_NETWORK_EVENTS_INFO)LockRequest( Irp, IrpSp );
|
(PAFD_ENUM_NETWORK_EVENTS_INFO)LockRequest( Irp, IrpSp );
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called (FCB %x)\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called (FCB %x)\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) {
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return LostSocket( Irp );
|
{
|
||||||
|
return LostSocket( Irp );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !EnumReq ) {
|
if (!EnumReq)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
|
{
|
||||||
0 );
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumReq->PollEvents = FCB->PollState;
|
EnumReq->PollEvents = FCB->PollState;
|
||||||
|
@ -332,37 +365,40 @@ AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
FCB->PollStatus,
|
FCB->PollStatus,
|
||||||
sizeof(EnumReq->EventStatus) );
|
sizeof(EnumReq->EventStatus) );
|
||||||
|
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp,
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
|
||||||
0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */
|
/* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */
|
||||||
static BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
|
static BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject )
|
||||||
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
PAFD_FCB FCB;
|
PAFD_FCB FCB;
|
||||||
UINT Signalled = 0;
|
UINT Signalled = 0;
|
||||||
PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
PAFD_POLL_INFO PollReq = (PAFD_POLL_INFO)Poll->Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
|
ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
|
||||||
|
|
||||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
for (i = 0; i < PollReq->HandleCount; i++)
|
||||||
if( !AFD_HANDLES(PollReq)[i].Handle ) continue;
|
{
|
||||||
|
if ( !AFD_HANDLES(PollReq)[i].Handle )
|
||||||
|
continue;
|
||||||
|
|
||||||
FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle;
|
FileObject = (PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle;
|
||||||
FCB = FileObject->FsContext;
|
FCB = FileObject->FsContext;
|
||||||
|
|
||||||
PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState;
|
PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState;
|
||||||
if( PollReq->Handles[i].Status ) {
|
if (PollReq->Handles[i].Status)
|
||||||
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n",
|
{
|
||||||
FCB, FCB->PollState));
|
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n", FCB, FCB->PollState));
|
||||||
Signalled++;
|
Signalled++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Signalled ? 1 : 0;
|
return Signalled ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
VOID PollReeval(PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
|
{
|
||||||
PAFD_ACTIVE_POLL Poll = NULL;
|
PAFD_ACTIVE_POLL Poll = NULL;
|
||||||
PLIST_ENTRY ThePollEnt = NULL;
|
PLIST_ENTRY ThePollEnt = NULL;
|
||||||
PAFD_FCB FCB;
|
PAFD_FCB FCB;
|
||||||
|
@ -377,30 +413,35 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
||||||
/* Take care of any event select signalling */
|
/* Take care of any event select signalling */
|
||||||
FCB = (PAFD_FCB)FileObject->FsContext;
|
FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
|
|
||||||
if( !FCB ) {
|
if (!FCB)
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
{
|
||||||
return;
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now signal normal select irps */
|
/* Now signal normal select irps */
|
||||||
ThePollEnt = DeviceExt->Polls.Flink;
|
ThePollEnt = DeviceExt->Polls.Flink;
|
||||||
|
|
||||||
while( ThePollEnt != &DeviceExt->Polls ) {
|
while (ThePollEnt != &DeviceExt->Polls)
|
||||||
Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
|
{
|
||||||
PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
|
||||||
AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
|
PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
|
||||||
|
|
||||||
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
if (UpdatePollWithFCB(Poll, FileObject))
|
||||||
ThePollEnt = ThePollEnt->Flink;
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
ThePollEnt = ThePollEnt->Flink;
|
||||||
SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS );
|
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
||||||
} else
|
SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS );
|
||||||
ThePollEnt = ThePollEnt->Flink;
|
}
|
||||||
|
else
|
||||||
|
ThePollEnt = ThePollEnt->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
|
|
||||||
if( FCB->EventSelect && (FCB->PollState & FCB->EventSelectTriggers) ) {
|
if ( FCB->EventSelect && (FCB->PollState & FCB->EventSelectTriggers) )
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Setting event %x\n", FCB->EventSelect));
|
AFD_DbgPrint(MID_TRACE,("Setting event %x\n", FCB->EventSelect));
|
||||||
KeSetEvent( FCB->EventSelect, IO_NETWORK_INCREMENT, FALSE );
|
KeSetEvent( FCB->EventSelect, IO_NETWORK_INCREMENT, FALSE );
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,14 @@
|
||||||
#include "tdiconn.h"
|
#include "tdiconn.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static NTSTATUS NTAPI SendComplete
|
static
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
NTSTATUS
|
||||||
PIRP Irp,
|
NTAPI
|
||||||
PVOID Context ) {
|
SendComplete
|
||||||
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PVOID Context )
|
||||||
|
{
|
||||||
NTSTATUS Status = Irp->IoStatus.Status;
|
NTSTATUS Status = Irp->IoStatus.Status;
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PLIST_ENTRY NextIrpEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
|
@ -38,39 +42,45 @@ static NTSTATUS NTAPI SendComplete
|
||||||
Irp->IoStatus.Status,
|
Irp->IoStatus.Status,
|
||||||
Irp->IoStatus.Information));
|
Irp->IoStatus.Information));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
|
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
|
||||||
FCB->SendIrp.InFlightRequest = NULL;
|
FCB->SendIrp.InFlightRequest = NULL;
|
||||||
/* Request is not in flight any longer */
|
/* Request is not in flight any longer */
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if (FCB->State == SOCKET_STATE_CLOSED)
|
||||||
|
{
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND]))
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
{
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
NextIrp->IoStatus.Information = 0;
|
||||||
if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
SocketStateUnlock( FCB );
|
|
||||||
return STATUS_FILE_CLOSED;
|
SocketStateUnlock(FCB);
|
||||||
|
return STATUS_FILE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) ) {
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
/* Complete all following send IRPs with error */
|
/* Complete all following send IRPs with error */
|
||||||
|
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND]))
|
||||||
NextIrpEntry =
|
{
|
||||||
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
NextIrp =
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
|
@ -81,8 +91,10 @@ static NTSTATUS NTAPI SendComplete
|
||||||
NextIrp->IoStatus.Status = Status;
|
NextIrp->IoStatus.Status = Status;
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Information = 0;
|
||||||
|
|
||||||
if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
if (NextIrp->MdlAddress)
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +108,10 @@ static NTSTATUS NTAPI SendComplete
|
||||||
FCB->Send.BytesUsed - Irp->IoStatus.Information );
|
FCB->Send.BytesUsed - Irp->IoStatus.Information );
|
||||||
FCB->Send.BytesUsed -= Irp->IoStatus.Information;
|
FCB->Send.BytesUsed -= Irp->IoStatus.Information;
|
||||||
|
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND]))
|
||||||
NextIrpEntry =
|
{
|
||||||
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
NextIrp =
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
|
||||||
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
|
||||||
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
SendReq = GetLockedData(NextIrp, NextIrpSp);
|
||||||
Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
|
Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount);
|
||||||
|
@ -110,7 +121,8 @@ static NTSTATUS NTAPI SendComplete
|
||||||
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
|
SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed;
|
||||||
TotalBytesCopied = 0;
|
TotalBytesCopied = 0;
|
||||||
|
|
||||||
for( i = 0; i < SendReq->BufferCount; i++ ) {
|
for (i = 0; i<SendReq->BufferCount; i++)
|
||||||
|
{
|
||||||
if (SpaceAvail < SendReq->BufferArray[i].len)
|
if (SpaceAvail < SendReq->BufferArray[i].len)
|
||||||
{
|
{
|
||||||
InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND],
|
InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND],
|
||||||
|
@ -118,8 +130,7 @@ static NTSTATUS NTAPI SendComplete
|
||||||
NextIrp = NULL;
|
NextIrp = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Map[i].BufferAddress =
|
Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode );
|
||||||
MmMapLockedPages( Map[i].Mdl, KernelMode );
|
|
||||||
|
|
||||||
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
|
RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed,
|
||||||
Map[i].BufferAddress,
|
Map[i].BufferAddress,
|
||||||
|
@ -144,7 +155,8 @@ static NTSTATUS NTAPI SendComplete
|
||||||
SendReq->BufferCount,
|
SendReq->BufferCount,
|
||||||
FALSE );
|
FALSE );
|
||||||
|
|
||||||
if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp);
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest(NextIrp, NextIrpSp);
|
||||||
|
|
||||||
IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT);
|
IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +165,8 @@ static NTSTATUS NTAPI SendComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some data is still waiting */
|
/* Some data is still waiting */
|
||||||
if( FCB->Send.BytesUsed ) {
|
if (FCB->Send.BytesUsed)
|
||||||
|
{
|
||||||
FCB->PollState &= ~AFD_EVENT_SEND;
|
FCB->PollState &= ~AFD_EVENT_SEND;
|
||||||
|
|
||||||
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
|
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
|
||||||
|
@ -164,7 +177,9 @@ static NTSTATUS NTAPI SendComplete
|
||||||
&FCB->SendIrp.Iosb,
|
&FCB->SendIrp.Iosb,
|
||||||
SendComplete,
|
SendComplete,
|
||||||
FCB );
|
FCB );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FCB->PollState |= AFD_EVENT_SEND;
|
FCB->PollState |= AFD_EVENT_SEND;
|
||||||
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
|
@ -175,10 +190,14 @@ static NTSTATUS NTAPI SendComplete
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI PacketSocketSendComplete
|
static
|
||||||
( PDEVICE_OBJECT DeviceObject,
|
NTSTATUS
|
||||||
PIRP Irp,
|
NTAPI
|
||||||
PVOID Context ) {
|
PacketSocketSendComplete
|
||||||
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PVOID Context)
|
||||||
|
{
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PLIST_ENTRY NextIrpEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
PIRP NextIrp;
|
PIRP NextIrp;
|
||||||
|
@ -187,7 +206,7 @@ static NTSTATUS NTAPI PacketSocketSendComplete
|
||||||
Irp->IoStatus.Status,
|
Irp->IoStatus.Status,
|
||||||
Irp->IoStatus.Information));
|
Irp->IoStatus.Information));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
|
ASSERT(FCB->SendIrp.InFlightRequest == Irp);
|
||||||
|
@ -201,19 +220,25 @@ static NTSTATUS NTAPI PacketSocketSendComplete
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if (FCB->State == SOCKET_STATE_CLOSED)
|
||||||
|
{
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) {
|
while (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND]))
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
{
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
|
||||||
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
NextIrp->IoStatus.Information = 0;
|
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
|
||||||
if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
NextIrp->IoStatus.Information = 0;
|
||||||
(void)IoSetCancelRoutine(NextIrp, NULL);
|
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
if (NextIrp->MdlAddress)
|
||||||
|
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
|
||||||
|
|
||||||
|
(void)IoSetCancelRoutine(NextIrp, NULL);
|
||||||
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
SocketStateUnlock( FCB );
|
|
||||||
return STATUS_FILE_CLOSED;
|
SocketStateUnlock( FCB );
|
||||||
|
return STATUS_FILE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock( FCB );
|
||||||
|
@ -221,12 +246,15 @@ static NTSTATUS NTAPI PacketSocketSendComplete
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp, BOOLEAN Short) {
|
AfdConnectedSocketWriteData
|
||||||
|
( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp, BOOLEAN Short )
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_SEND_INFO SendReq;
|
PAFD_SEND_INFO SendReq;
|
||||||
ULONG Information;
|
ULONG Information;
|
||||||
UINT TotalBytesCopied = 0, i, SpaceAvail = 0;
|
UINT TotalBytesCopied = 0, i, SpaceAvail = 0;
|
||||||
|
@ -234,19 +262,19 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket( Irp );
|
||||||
|
|
||||||
if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
|
if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
|
||||||
{
|
{
|
||||||
PAFD_SEND_INFO_UDP SendReq;
|
PAFD_SEND_INFO_UDP SendReq;
|
||||||
PTDI_CONNECTION_INFORMATION TargetAddress;
|
PTDI_CONNECTION_INFORMATION TargetAddress;
|
||||||
|
|
||||||
/* Check that the socket is bound */
|
/* Check that the socket is bound */
|
||||||
if( FCB->State != SOCKET_STATE_BOUND || !FCB->RemoteAddress )
|
if (FCB->State != SOCKET_STATE_BOUND || !FCB->RemoteAddress)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp,
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
0 );
|
|
||||||
|
|
||||||
if( !(SendReq = LockRequest( Irp, IrpSp )) )
|
if (!(SendReq = LockRequest(Irp, IrpSp)))
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
||||||
|
|
||||||
/* Must lock buffers before handing off user data */
|
/* Must lock buffers before handing off user data */
|
||||||
|
@ -255,14 +283,15 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
FALSE, FALSE );
|
FALSE, FALSE );
|
||||||
|
|
||||||
if( !SendReq->BufferArray ) {
|
if ( !SendReq->BufferArray )
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
|
{
|
||||||
Irp, 0 );
|
return UnlockAndMaybeComplete(FCB, STATUS_ACCESS_VIOLATION, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = TdiBuildConnectionInfo( &TargetAddress, FCB->RemoteAddress );
|
Status = TdiBuildConnectionInfo( &TargetAddress, FCB->RemoteAddress );
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
Status = TdiSendDatagram
|
Status = TdiSendDatagram
|
||||||
( &FCB->SendIrp.InFlightRequest,
|
( &FCB->SendIrp.InFlightRequest,
|
||||||
FCB->AddressFile.Object,
|
FCB->AddressFile.Object,
|
||||||
|
@ -276,7 +305,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
ExFreePool( TargetAddress );
|
ExFreePool( TargetAddress );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
|
if (Status == STATUS_PENDING)
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
|
||||||
|
|
||||||
|
@ -287,7 +317,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, Information );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, Information );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(SendReq = LockRequest( Irp, IrpSp )) )
|
if( !(SendReq = LockRequest(Irp, IrpSp)))
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, STATUS_NO_MEMORY, Irp, TotalBytesCopied );
|
( FCB, STATUS_NO_MEMORY, Irp, TotalBytesCopied );
|
||||||
|
|
||||||
|
@ -296,20 +326,23 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
FALSE, FALSE );
|
FALSE, FALSE );
|
||||||
|
|
||||||
if( !SendReq->BufferArray ) {
|
if (!SendReq->BufferArray)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
|
{
|
||||||
Irp, 0 );
|
return UnlockAndMaybeComplete(FCB, STATUS_ACCESS_VIOLATION, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Socket state %d\n", FCB->State));
|
AFD_DbgPrint(MID_TRACE,("Socket state %d\n", FCB->State));
|
||||||
|
|
||||||
if( FCB->State != SOCKET_STATE_CONNECTED ) {
|
if (FCB->State != SOCKET_STATE_CONNECTED)
|
||||||
if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
|
{
|
||||||
|
if (SendReq->AfdFlags & AFD_IMMEDIATE)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, STATUS_CANT_WAIT, Irp, 0);
|
||||||
( FCB, STATUS_CANT_WAIT, Irp, 0 );
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
|
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
|
||||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
|
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
|
||||||
}
|
}
|
||||||
|
@ -323,8 +356,10 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
|
AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n",
|
||||||
SpaceAvail));
|
SpaceAvail));
|
||||||
|
|
||||||
for( i = 0; FCB->Send.BytesUsed < FCB->Send.Size &&
|
for (i = 0;
|
||||||
i < SendReq->BufferCount; i++ ) {
|
FCB->Send.BytesUsed < FCB->Send.Size && i < SendReq->BufferCount;
|
||||||
|
i++ )
|
||||||
|
{
|
||||||
|
|
||||||
if (SpaceAvail < SendReq->BufferArray[i].len)
|
if (SpaceAvail < SendReq->BufferArray[i].len)
|
||||||
{
|
{
|
||||||
|
@ -352,11 +387,11 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
SpaceAvail -= SendReq->BufferArray[i].len;
|
SpaceAvail -= SendReq->BufferArray[i].len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( TotalBytesCopied == 0 ) {
|
if (TotalBytesCopied == 0)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
|
AFD_DbgPrint(MID_TRACE,("Empty send\n"));
|
||||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, TotalBytesCopied);
|
||||||
( FCB, STATUS_SUCCESS, Irp, TotalBytesCopied );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NoSpace)
|
if (!NoSpace)
|
||||||
|
@ -367,12 +402,15 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( SendReq->AfdFlags & AFD_IMMEDIATE ) {
|
if (SendReq->AfdFlags & AFD_IMMEDIATE)
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||||
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE );
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, STATUS_CANT_WAIT, Irp, 0 );
|
( FCB, STATUS_CANT_WAIT, Irp, 0 );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
|
AFD_DbgPrint(MID_TRACE,("Queuing request\n"));
|
||||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
|
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_SEND );
|
||||||
}
|
}
|
||||||
|
@ -389,57 +427,62 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
SendComplete,
|
SendComplete,
|
||||||
FCB );
|
FCB );
|
||||||
|
|
||||||
if( Status == STATUS_PENDING )
|
if (Status == STATUS_PENDING)
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
|
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
|
||||||
Status, TotalBytesCopied));
|
Status, TotalBytesCopied));
|
||||||
}
|
}
|
||||||
|
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, Status, Irp, TotalBytesCopied);
|
||||||
( FCB, Status, Irp, TotalBytesCopied );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
NTSTATUS
|
||||||
AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
NTAPI
|
||||||
PIO_STACK_LOCATION IrpSp) {
|
AfdPacketSocketWriteData
|
||||||
|
( PDEVICE_OBJECT DeviceObject,
|
||||||
|
PIRP Irp,
|
||||||
|
PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PTDI_CONNECTION_INFORMATION TargetAddress;
|
PTDI_CONNECTION_INFORMATION TargetAddress;
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
|
||||||
PAFD_SEND_INFO_UDP SendReq;
|
PAFD_SEND_INFO_UDP SendReq;
|
||||||
ULONG Information;
|
ULONG Information;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
|
if (!SocketAcquireStateLock(FCB))
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
/* Check that the socket is bound */
|
/* Check that the socket is bound */
|
||||||
if( FCB->State != SOCKET_STATE_BOUND &&
|
if ( FCB->State != SOCKET_STATE_BOUND &&
|
||||||
FCB->State != SOCKET_STATE_CREATED)
|
FCB->State != SOCKET_STATE_CREATED)
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
|
||||||
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
|
|
||||||
if( !(SendReq = LockRequest( Irp, IrpSp )) )
|
if( !(SendReq = LockRequest(Irp, IrpSp)))
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
|
||||||
|
|
||||||
if (FCB->State == SOCKET_STATE_CREATED)
|
if (FCB->State == SOCKET_STATE_CREATED)
|
||||||
{
|
{
|
||||||
if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
|
if (FCB->LocalAddress)
|
||||||
|
ExFreePool(FCB->LocalAddress);
|
||||||
FCB->LocalAddress =
|
FCB->LocalAddress =
|
||||||
TaBuildNullTransportAddress( ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)->
|
TaBuildNullTransportAddress(
|
||||||
Address[0].AddressType );
|
((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)->Address[0].AddressType);
|
||||||
|
|
||||||
if( FCB->LocalAddress ) {
|
if (FCB->LocalAddress)
|
||||||
|
{
|
||||||
Status = WarmSocketForBind( FCB );
|
Status = WarmSocketForBind( FCB );
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) )
|
if (NT_SUCCESS(Status))
|
||||||
FCB->State = SOCKET_STATE_BOUND;
|
FCB->State = SOCKET_STATE_BOUND;
|
||||||
else
|
else
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
|
||||||
} else
|
}
|
||||||
return UnlockAndMaybeComplete
|
else
|
||||||
( FCB, STATUS_NO_MEMORY, Irp, 0 );
|
return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
|
SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
|
||||||
|
@ -447,9 +490,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
FALSE, FALSE );
|
FALSE, FALSE );
|
||||||
|
|
||||||
if( !SendReq->BufferArray )
|
if (!SendReq->BufferArray)
|
||||||
return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
|
return UnlockAndMaybeComplete(FCB, STATUS_ACCESS_VIOLATION, Irp, 0);
|
||||||
Irp, 0 );
|
|
||||||
|
|
||||||
AFD_DbgPrint
|
AFD_DbgPrint
|
||||||
(MID_TRACE,("RemoteAddress #%d Type %d\n",
|
(MID_TRACE,("RemoteAddress #%d Type %d\n",
|
||||||
|
@ -463,7 +505,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
/* Check the size of the Address given ... */
|
/* Check the size of the Address given ... */
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
FCB->PollState &= ~AFD_EVENT_SEND;
|
FCB->PollState &= ~AFD_EVENT_SEND;
|
||||||
|
|
||||||
Status = TdiSendDatagram
|
Status = TdiSendDatagram
|
||||||
|
@ -476,10 +519,11 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PacketSocketSendComplete,
|
PacketSocketSendComplete,
|
||||||
FCB );
|
FCB );
|
||||||
|
|
||||||
ExFreePool( TargetAddress );
|
ExFreePool(TargetAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
|
if (Status == STATUS_PENDING)
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
|
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x\n", Status));
|
||||||
|
|
||||||
|
@ -487,6 +531,7 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
* point. */
|
* point. */
|
||||||
Information = SendReq->BufferArray[0].len;
|
Information = SendReq->BufferArray[0].len;
|
||||||
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
||||||
|
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, Information );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, Information );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -483,57 +483,61 @@ NTSTATUS DispTdiConnect(
|
||||||
* Status of operation
|
* Status of operation
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PCONNECTION_ENDPOINT Connection;
|
PCONNECTION_ENDPOINT Connection;
|
||||||
PTDI_REQUEST_KERNEL Parameters;
|
PTDI_REQUEST_KERNEL Parameters;
|
||||||
PTRANSPORT_CONTEXT TranContext;
|
PTRANSPORT_CONTEXT TranContext;
|
||||||
PIO_STACK_LOCATION IrpSp;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiConnect] Called\n"));
|
TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiConnect] Called\n"));
|
||||||
|
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
/* Get associated connection endpoint file object. Quit if none exists */
|
/* Get associated connection endpoint file object. Quit if none exists */
|
||||||
|
|
||||||
TranContext = IrpSp->FileObject->FsContext;
|
TranContext = IrpSp->FileObject->FsContext;
|
||||||
if (!TranContext) {
|
if (!TranContext)
|
||||||
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
|
||||||
goto done;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
||||||
if (!Connection) {
|
if (!Connection)
|
||||||
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
|
||||||
goto done;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
|
||||||
|
|
||||||
Status = DispPrepareIrpForCancel(TranContext->Handle.ConnectionContext,
|
Status = DispPrepareIrpForCancel(TranContext->Handle.ConnectionContext,
|
||||||
Irp,
|
Irp,
|
||||||
DispCancelRequest);
|
DispCancelRequest);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = TCPConnect(
|
Status = TCPConnect(
|
||||||
TranContext->Handle.ConnectionContext,
|
TranContext->Handle.ConnectionContext,
|
||||||
Parameters->RequestConnectionInformation,
|
Parameters->RequestConnectionInformation,
|
||||||
Parameters->ReturnConnectionInformation,
|
Parameters->ReturnConnectionInformation,
|
||||||
DispDataRequestComplete,
|
DispDataRequestComplete,
|
||||||
Irp );
|
Irp );
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (Status != STATUS_PENDING) {
|
if (Status != STATUS_PENDING)
|
||||||
DispDataRequestComplete(Irp, Status, 0);
|
{
|
||||||
} else
|
DispDataRequestComplete(Irp, Status, 0);
|
||||||
IoMarkIrpPending(Irp);
|
}
|
||||||
|
else
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiConnect] TCP Connect returned %08x\n", Status));
|
TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiConnect] TCP Connect returned %08x\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS DispTdiDisconnect(
|
NTSTATUS DispTdiDisconnect(
|
||||||
|
@ -546,51 +550,54 @@ NTSTATUS DispTdiDisconnect(
|
||||||
* Status of operation
|
* Status of operation
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PTDI_REQUEST_KERNEL_DISCONNECT DisReq;
|
PTDI_REQUEST_KERNEL_DISCONNECT DisReq;
|
||||||
PCONNECTION_ENDPOINT Connection;
|
PCONNECTION_ENDPOINT Connection;
|
||||||
PTRANSPORT_CONTEXT TranContext;
|
PTRANSPORT_CONTEXT TranContext;
|
||||||
PIO_STACK_LOCATION IrpSp;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiDisconnect] Called\n"));
|
TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiDisconnect] Called\n"));
|
||||||
|
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
|
DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
|
||||||
|
|
||||||
/* Get associated connection endpoint file object. Quit if none exists */
|
/* Get associated connection endpoint file object. Quit if none exists */
|
||||||
|
|
||||||
TranContext = IrpSp->FileObject->FsContext;
|
TranContext = IrpSp->FileObject->FsContext;
|
||||||
if (!TranContext) {
|
if (!TranContext)
|
||||||
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
|
{
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
|
||||||
goto done;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
||||||
if (!Connection)
|
if (!Connection)
|
||||||
{
|
{
|
||||||
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
|
TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = TCPDisconnect(
|
Status = TCPDisconnect(
|
||||||
TranContext->Handle.ConnectionContext,
|
TranContext->Handle.ConnectionContext,
|
||||||
DisReq->RequestFlags,
|
DisReq->RequestFlags,
|
||||||
DisReq->RequestConnectionInformation,
|
DisReq->RequestConnectionInformation,
|
||||||
DisReq->ReturnConnectionInformation,
|
DisReq->ReturnConnectionInformation,
|
||||||
DispDataRequestComplete,
|
DispDataRequestComplete,
|
||||||
Irp );
|
Irp );
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (Status != STATUS_PENDING) {
|
if (Status != STATUS_PENDING)
|
||||||
DispDataRequestComplete(Irp, Status, 0);
|
{
|
||||||
} else
|
DispDataRequestComplete(Irp, Status, 0);
|
||||||
IoMarkIrpPending(Irp);
|
}
|
||||||
|
else
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiDisconnect] TCP Disconnect returned %08x\n", Status));
|
TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiDisconnect] TCP Disconnect returned %08x\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -185,10 +185,10 @@ TCPAcceptEventHandler(void *arg, struct tcp_pcb *newpcb)
|
||||||
|
|
||||||
if (Status == STATUS_SUCCESS)
|
if (Status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
DbgPrint("[IP, TCPAcceptEventHandler] newpcb->state = %s, listen_pcb->state = %s, newpcb->id = %d\n",
|
DbgPrint("[IP, TCPAcceptEventHandler] newpcb->state = %s, listen_pcb->state = %s, newpcb = 0x%x\n",
|
||||||
tcp_state_str[newpcb->state],
|
tcp_state_str[newpcb->state],
|
||||||
tcp_state_str[((struct tcp_pcb*)Connection->SocketContext)->state],
|
tcp_state_str[((struct tcp_pcb*)Connection->SocketContext)->state],
|
||||||
newpcb->identifier);
|
newpcb);
|
||||||
|
|
||||||
LockObject(Bucket->AssociatedEndpoint, &OldIrql);
|
LockObject(Bucket->AssociatedEndpoint, &OldIrql);
|
||||||
|
|
||||||
|
@ -203,6 +203,8 @@ TCPAcceptEventHandler(void *arg, struct tcp_pcb *newpcb)
|
||||||
DbgPrint("[IP, TCPAcceptEventHandler] Trying to unlock Bucket->AssociatedEndpoint\n");
|
DbgPrint("[IP, TCPAcceptEventHandler] Trying to unlock Bucket->AssociatedEndpoint\n");
|
||||||
UnlockObject(Bucket->AssociatedEndpoint, OldIrql);
|
UnlockObject(Bucket->AssociatedEndpoint, OldIrql);
|
||||||
|
|
||||||
|
/* sanity assert...this should never be in a LISTEN state */
|
||||||
|
ASSERT(((struct tcp_pcb*)OldSocketContext)->state == CLOSED);
|
||||||
/* free socket context created in FileOpenConnection, as we're using a new
|
/* free socket context created in FileOpenConnection, as we're using a new
|
||||||
one; we free it asynchornously because otherwise we create a dedlock */
|
one; we free it asynchornously because otherwise we create a dedlock */
|
||||||
ChewCreate(SocketContextCloseWorker, OldSocketContext);
|
ChewCreate(SocketContextCloseWorker, OldSocketContext);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue