[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:
Claudiu Mihail 2011-06-21 11:46:47 +00:00
parent 8e61bd7196
commit 7ba87c3d72
12 changed files with 1375 additions and 1036 deletions

View file

@ -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 );
} }

View file

@ -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,15 +246,15 @@ 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 ); ExFreePool( FCB->Recv.Window );
FCB->Recv.Window = NULL; FCB->Recv.Window = NULL;
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -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)
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);
} }
if( NT_SUCCESS(Status) ) { if (NT_SUCCESS(Status))
Status = MakeSocketIntoConnection( FCB ); {
Status = MakeSocketIntoConnection(FCB);
if( !NT_SUCCESS(Status) ) { if (!NT_SUCCESS(Status))
SocketStateUnlock( FCB ); {
SocketStateUnlock(FCB);
return Status; 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,7 +381,8 @@ 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,
@ -368,23 +390,24 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
FCB->FilledConnectOptions); FCB->FilledConnectOptions);
} }
if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { if (!IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND]))
{
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
Tail.Overlay.ListEntry);
AFD_DbgPrint(MID_TRACE,("Launching send request %x\n", NextIrp)); AFD_DbgPrint(MID_TRACE,("Launching send request %x\n", NextIrp));
Status = AfdConnectedSocketWriteData
( DeviceObject, Status = AfdConnectedSocketWriteData(DeviceObject,
NextIrp, NextIrp,
IoGetCurrentIrpStackLocation( NextIrp ), IoGetCurrentIrpStackLocation( NextIrp ),
FALSE ); FALSE);
} }
if( Status == STATUS_PENDING ) if (Status == STATUS_PENDING)
Status = STATUS_SUCCESS; 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)
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;
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;

View file

@ -12,22 +12,24 @@
#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;
} }
@ -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,19 +59,22 @@ 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 ); ExFreePool( FCB->Context );
FCB->ContextSize = 0; FCB->ContextSize = 0;
} }
@ -75,7 +82,8 @@ AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp,
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;

View file

@ -13,25 +13,29 @@
#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 ) { {
switch( InfoReq->InformationClass )
{
case AFD_INFO_RECEIVE_WINDOW_SIZE: case AFD_INFO_RECEIVE_WINDOW_SIZE:
InfoReq->Information.Ulong = FCB->Recv.Size; InfoReq->Information.Ulong = FCB->Recv.Size;
break; break;
@ -69,7 +73,6 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
InfoReq->Information.Ulong++; InfoReq->Information.Ulong++;
CurrentEntry = CurrentEntry->Flink; CurrentEntry = CurrentEntry->Flink;
} }
break; break;
default: default:
@ -78,31 +81,38 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
break; break;
} }
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n")); AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n"));
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
} _SEH2_END; }
_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) { {
switch (InfoReq->InformationClass)
{
case AFD_INFO_BLOCKING_MODE: case AFD_INFO_BLOCKING_MODE:
AFD_DbgPrint(MID_TRACE,("Blocking mode set to %d\n", InfoReq->Information.Ulong)); AFD_DbgPrint(MID_TRACE,("Blocking mode set to %d\n", InfoReq->Information.Ulong));
FCB->BlockingMode = InfoReq->Information.Ulong; FCB->BlockingMode = InfoReq->Information.Ulong;
@ -111,26 +121,32 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MIN_TRACE,("Unknown request %d\n", InfoReq->InformationClass)); AFD_DbgPrint(MIN_TRACE,("Unknown request %d\n", InfoReq->InformationClass));
break; break;
} }
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
} _SEH2_END; }
_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 );
} }
@ -141,44 +157,52 @@ AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
FALSE, FALSE,
NULL ); NULL );
if( Mdl != NULL ) { if( Mdl != NULL )
_SEH2_TRY { {
_SEH2_TRY
{
MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess ); MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
} _SEH2_END; }
_SEH2_END;
if( NT_SUCCESS(Status) ) { if (NT_SUCCESS(Status))
Status = TdiQueryInformation {
( FCB->Connection.Object ? FCB->Connection.Object : FCB->AddressFile.Object, Status = TdiQueryInformation(
FCB->Connection.Object ? FCB->Connection.Object : FCB->AddressFile.Object,
TDI_QUERY_ADDRESS_INFO, TDI_QUERY_ADDRESS_INFO,
Mdl ); 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); MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoModifyAccess);
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
} _SEH2_END; }
_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;
} }

View file

@ -12,11 +12,15 @@
#include "tdiconn.h" #include "tdiconn.h"
#include "debug.h" #include "debug.h"
static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt, static
NTSTATUS
SatisfyAccept
( PAFD_DEVICE_EXTENSION DeviceExt,
PIRP Irp, PIRP Irp,
PFILE_OBJECT NewFileObject, PFILE_OBJECT NewFileObject,
PAFD_TDI_OBJECT_QELT Qelt ) { PAFD_TDI_OBJECT_QELT Qelt )
PAFD_FCB FCB = NewFileObject->FsContext; {
PAFD_FCB FCB = (PAFD_FCB)NewFileObject->FsContext;
NTSTATUS Status; NTSTATUS Status;
if( !SocketAcquireStateLock( FCB ) ) if( !SocketAcquireStateLock( FCB ) )
@ -28,11 +32,12 @@ 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 );
if( !FCB->RemoteAddress ) FCB->RemoteAddress = TaCopyTransportAddress(Qelt->ConnInfo->RemoteAddress);
if (!FCB->RemoteAddress)
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
else else
Status = MakeSocketIntoConnection( FCB ); Status = MakeSocketIntoConnection( FCB );
@ -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;
} }
} }

View file

@ -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
LockBuffers
( PAFD_WSABUF Buf, UINT Count,
PVOID AddressBuf, PINT AddressLen, PVOID AddressBuf, PINT AddressLen,
BOOLEAN Write, BOOLEAN LockAddress ) { 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,48 +155,64 @@ 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", AFD_DbgPrint(MID_TRACE,("Locking buffer %d (%x:%d)\n",
i, NewBuf[i].buf, NewBuf[i].len)); 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, MapBuf[i].Mdl = IoAllocateMdl( NewBuf[i].buf,
NewBuf[i].len, NewBuf[i].len,
FALSE, FALSE,
FALSE, FALSE,
NULL ); NULL );
} else { }
else
{
MapBuf[i].Mdl = NULL; MapBuf[i].Mdl = NULL;
continue; continue;
} }
AFD_DbgPrint(MID_TRACE,("NewMdl @ %x\n", MapBuf[i].Mdl)); AFD_DbgPrint(MID_TRACE,("NewMdl @ %x\n", MapBuf[i].Mdl));
if( MapBuf[i].Mdl ) { if (MapBuf[i].Mdl)
{
AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n")); AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
_SEH2_TRY { _SEH2_TRY
{
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode, MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
Write ? IoModifyAccess : IoReadAccess ); Write ? IoModifyAccess : IoReadAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
LockFailed = TRUE; LockFailed = TRUE;
} _SEH2_END; }
_SEH2_END;
AFD_DbgPrint(MID_TRACE,("MmProbeAndLock finished\n")); AFD_DbgPrint(MID_TRACE,("MmProbeAndLock finished\n"));
if( LockFailed ) { if (LockFailed)
{
IoFreeMdl( MapBuf[i].Mdl ); IoFreeMdl( MapBuf[i].Mdl );
MapBuf[i].Mdl = NULL; MapBuf[i].Mdl = NULL;
ExFreePool( NewBuf ); ExFreePool( NewBuf );
return NULL; return NULL;
} }
} else { }
else
{
ExFreePool( NewBuf ); ExFreePool( NewBuf );
return NULL; return NULL;
} }
@ -183,40 +224,50 @@ 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 ) { {
if (Map[i].Mdl)
{
MmUnlockPages( Map[i].Mdl ); MmUnlockPages( Map[i].Mdl );
IoFreeMdl( Map[i].Mdl ); IoFreeMdl( Map[i].Mdl );
Map[i].Mdl = NULL; 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].Status = 0;
FileObjects[i].Events = HandleArray[i].Events; 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)
continue;
if (NT_SUCCESS(Status))
{
Status = ObReferenceObjectByHandle Status = ObReferenceObjectByHandle
( (PVOID)HandleArray[i].Handle, ( (PVOID)HandleArray[i].Handle,
FILE_ALL_ACCESS, FILE_ALL_ACCESS,
@ -226,32 +277,37 @@ PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
NULL ); 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 ); {
UnlockHandles(FileObjects, HandleCount);
return NULL; 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 ) {
if (HandleArray[i].Handle)
ObDereferenceObject( (PVOID)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;
} }

View file

@ -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;
@ -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,8 +1047,7 @@ 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,
@ -1049,7 +1056,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
&DeviceObject ); &DeviceObject );
/* failure */ /* failure */
if(!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return (Status); return (Status);
} }

View file

@ -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
NTSTATUS
TryToSatisfyRecvRequestFromBuffer
( PAFD_FCB FCB,
PAFD_RECV_INFO RecvReq, PAFD_RECV_INFO RecvReq,
PUINT TotalBytesCopied ) { 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)
RetStatus = Status;
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 );
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,36 +198,41 @@ 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)
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
(void)IoSetCancelRoutine(NextIrp, NULL); (void)IoSetCancelRoutine(NextIrp, NULL);
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
} }
@ -218,17 +240,20 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
} }
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,10 +285,13 @@ 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]); NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp); NextIrpSp = IoGetCurrentIrpStackLocation(NextIrp);
@ -268,13 +299,19 @@ NTSTATUS NTAPI ReceiveComplete
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0; NextIrp->IoStatus.Information = 0;
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
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 );
} }
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
return STATUS_FILE_CLOSED; return STATUS_FILE_CLOSED;
} else if( FCB->State == SOCKET_STATE_LISTENING ) { }
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
NTAPI
SatisfyPacketRecvRequest
( PAFD_FCB FCB, PIRP Irp,
PAFD_STORED_DATAGRAM DatagramRecv, PAFD_STORED_DATAGRAM DatagramRecv,
PUINT TotalBytesCopied ) { 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,15 +523,17 @@ 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]); NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
@ -487,20 +541,24 @@ PacketSocketRecvComplete(
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0; NextIrp->IoStatus.Information = 0;
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE); UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
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 );
} }
/* 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); DatagramRecvEntry = RemoveHeadList(&FCB->DatagramList);
DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry); DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry);
ExFreePool( DatagramRecv->Address ); ExFreePool( DatagramRecv->Address );
ExFreePool( DatagramRecv ); ExFreePool( DatagramRecv );
} }
SocketStateUnlock( FCB ); SocketStateUnlock(FCB);
return STATUS_FILE_CLOSED; return STATUS_FILE_CLOSED;
} }
@ -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 );
} }

View file

@ -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,21 +34,23 @@ 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].Events = HandleArray[i].Status;
HandleArray[i].Status = 0; 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].Status = 0;
HandleArray[i].Events = 0; HandleArray[i].Events = 0;
} }
@ -55,12 +58,11 @@ VOID ZeroEvents( PAFD_HANDLE HandleArray,
/* 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;
@ -76,9 +78,10 @@ VOID SignalSocket(
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,18 +145,22 @@ 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); Poll = CONTAINING_RECORD(ListEntry, AFD_ACTIVE_POLL, ListEntry);
ListEntry = ListEntry->Flink; 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 );
} }
@ -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.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
return STATUS_NO_MEMORY; 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,26 +229,29 @@ 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){ if (Poll)
{
Poll->Irp = Irp; Poll->Irp = Irp;
Poll->DeviceExt = DeviceExt; Poll->DeviceExt = DeviceExt;
Poll->Exclusive = Exclusive; Poll->Exclusive = Exclusive;
@ -246,7 +269,9 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
Status = STATUS_PENDING; Status = STATUS_PENDING;
IoMarkIrpPending( Irp ); IoMarkIrpPending( Irp );
(void)IoSetCancelRoutine(Irp, AfdCancelHandler); (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;
} }
@ -259,33 +284,38 @@ 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(
(PVOID)EventSelectInfo->EventObject,
FILE_ALL_ACCESS, FILE_ALL_ACCESS,
ExEventObjectType, ExEventObjectType,
UserMode, UserMode,
@ -296,7 +326,9 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
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;
@ -304,27 +336,28 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
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,29 +365,31 @@ 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++;
} }
} }
@ -362,7 +397,8 @@ static BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject
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,7 +413,8 @@ 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 ); KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
return; return;
} }
@ -385,22 +422,26 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
/* 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 ); Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
PollReq = Poll->Irp->AssociatedIrp.SystemBuffer; PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll)); AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
if( UpdatePollWithFCB( Poll, FileObject ) ) { if (UpdatePollWithFCB(Poll, FileObject))
{
ThePollEnt = ThePollEnt->Flink; ThePollEnt = ThePollEnt->Flink;
AFD_DbgPrint(MID_TRACE,("Signalling socket\n")); AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS ); SignalSocket( Poll, NULL, PollReq, STATUS_SUCCESS );
} else }
else
ThePollEnt = ThePollEnt->Flink; 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 );
} }

View file

@ -12,10 +12,14 @@
#include "tdiconn.h" #include "tdiconn.h"
#include "debug.h" #include "debug.h"
static NTSTATUS NTAPI SendComplete static
NTSTATUS
NTAPI
SendComplete
( 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;
@ -38,16 +42,18 @@ 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]); NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
@ -55,22 +61,26 @@ static NTSTATUS NTAPI SendComplete
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0; NextIrp->IoStatus.Information = 0;
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
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 );
} }
SocketStateUnlock( FCB );
SocketStateUnlock(FCB);
return STATUS_FILE_CLOSED; 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,7 +91,9 @@ 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)
UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
(void)IoSetCancelRoutine(NextIrp, NULL); (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
NTSTATUS
NTAPI
PacketSocketSendComplete
( 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;
@ -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,17 +220,23 @@ 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]); NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]);
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
NextIrp->IoStatus.Information = 0; NextIrp->IoStatus.Information = 0;
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 );
} }
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
return STATUS_FILE_CLOSED; return STATUS_FILE_CLOSED;
} }
@ -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 );
} }

View file

@ -496,14 +496,16 @@ NTSTATUS DispTdiConnect(
/* 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")); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto done; 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;
@ -525,10 +527,12 @@ NTSTATUS DispTdiConnect(
Irp ); Irp );
} }
done: done:
if (Status != STATUS_PENDING) { if (Status != STATUS_PENDING)
{
DispDataRequestComplete(Irp, Status, 0); DispDataRequestComplete(Irp, Status, 0);
} else }
else
IoMarkIrpPending(Irp); 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));
@ -560,7 +564,8 @@ NTSTATUS DispTdiDisconnect(
/* 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")); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto done; goto done;
@ -582,10 +587,12 @@ NTSTATUS DispTdiDisconnect(
DispDataRequestComplete, DispDataRequestComplete,
Irp ); Irp );
done: done:
if (Status != STATUS_PENDING) { if (Status != STATUS_PENDING)
{
DispDataRequestComplete(Irp, Status, 0); DispDataRequestComplete(Irp, Status, 0);
} else }
else
IoMarkIrpPending(Irp); 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));

View file

@ -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);