mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
tcpip: fix for udp socket close.
ws2_32: unstub WSAFDIsSet, small amount of work on select msafd: select fixes afd: major select overhaul - 1 exit point for poll objects from the deviceext - make sure to cancel the timer - UpdatePollWithFCB now runs at DISPATCH_LEVEL in every case - Added handle locks so we can signal and check handles properly svn path=/trunk/; revision=11684
This commit is contained in:
parent
4a7d199e30
commit
2c9bba03b5
11 changed files with 342 additions and 274 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: lock.c,v 1.6 2004/11/15 18:24:57 arty Exp $
|
||||
/* $Id: lock.c,v 1.7 2004/11/17 05:17:22 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/lock.c
|
||||
|
@ -114,6 +114,40 @@ VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address ) {
|
|||
ExFreePool( Buf );
|
||||
}
|
||||
|
||||
/* Produce a kernel-land handle array with handles replaced by object
|
||||
* pointers. This will allow the system to do proper alerting */
|
||||
PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
|
||||
UINT i;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAFD_HANDLE FileObjects = ExAllocatePool
|
||||
( NonPagedPool, HandleCount * sizeof(AFD_HANDLE) );
|
||||
|
||||
for( i = 0; FileObjects && i < HandleCount; i++ ) {
|
||||
HandleArray[i].Status = 0;
|
||||
HandleArray[i].Events = HandleArray[i].Events;
|
||||
Status = ObReferenceObjectByHandle
|
||||
( (PVOID)HandleArray[i].Handle,
|
||||
FILE_ALL_ACCESS,
|
||||
NULL,
|
||||
KernelMode,
|
||||
(PVOID*)&FileObjects[i].Handle,
|
||||
NULL );
|
||||
}
|
||||
|
||||
return FileObjects;
|
||||
}
|
||||
|
||||
VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
|
||||
UINT i;
|
||||
|
||||
for( i = 0; i < HandleCount; i++ ) {
|
||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
||||
}
|
||||
|
||||
ExFreePool( HandleArray );
|
||||
}
|
||||
|
||||
/* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
|
||||
UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: main.c,v 1.11 2004/11/16 18:07:57 chorns Exp $
|
||||
/* $Id: main.c,v 1.12 2004/11/17 05:17:22 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/main.c
|
||||
|
@ -212,6 +212,9 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB));
|
||||
|
||||
FileObject->FsContext = NULL;
|
||||
FCB->PollState |= AFD_EVENT_CLOSE;
|
||||
PollReeval( FCB->DeviceExt, FileObject );
|
||||
|
||||
DestroySocket( FCB );
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: read.c,v 1.10 2004/11/15 18:24:57 arty Exp $
|
||||
/* $Id: read.c,v 1.11 2004/11/17 05:17:22 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/read.c
|
||||
|
@ -416,7 +416,8 @@ PacketSocketRecvComplete(
|
|||
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
|
||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||
}
|
||||
} else
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
|
||||
/* Now relaunch the datagram request */
|
||||
|
@ -483,9 +484,6 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
return UnlockAndMaybeComplete
|
||||
( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
|
||||
} else {
|
||||
if( IsListEmpty( &FCB->DatagramList ) )
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
|
||||
Status = SatisfyPacketRecvRequest
|
||||
( FCB, Irp, DatagramRecv,
|
||||
(PUINT)&Irp->IoStatus.Information );
|
||||
|
@ -493,10 +491,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
|
||||
}
|
||||
} else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||
Status = STATUS_CANT_WAIT;
|
||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
|
||||
} else {
|
||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: select.c,v 1.5 2004/11/15 18:24:57 arty Exp $
|
||||
/* $Id: select.c,v 1.6 2004/11/17 05:17:22 arty Exp $
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/net/afd/afd/select.c
|
||||
|
@ -26,58 +26,36 @@ VOID ZeroEvents( PAFD_HANDLE HandleArray,
|
|||
UINT HandleCount ) {
|
||||
UINT i;
|
||||
|
||||
for( i = 0; i < HandleCount; i++ ) {
|
||||
HandleArray[i].Events = 0;
|
||||
for( i = 0; i < HandleCount; i++ )
|
||||
HandleArray[i].Status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
ScanForImmediateTrigger( PAFD_HANDLE HandleArray,
|
||||
UINT HandleCount,
|
||||
PUINT HandlesSet ) {
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PFILE_OBJECT FileObject;
|
||||
PAFD_FCB FCB;
|
||||
UINT i;
|
||||
BOOLEAN ShouldReturnNow = FALSE;
|
||||
VOID RemoveSelect( PAFD_ACTIVE_POLL Poll ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||
|
||||
for( i = 0; i < HandleCount && NT_SUCCESS(Status); i++ ) {
|
||||
HandleArray[i].Status = 0;
|
||||
Status =
|
||||
ObReferenceObjectByHandle
|
||||
( (PVOID)HandleArray[i].Handle,
|
||||
FILE_ALL_ACCESS,
|
||||
NULL,
|
||||
KernelMode,
|
||||
(PVOID*)&FileObject,
|
||||
NULL );
|
||||
RemoveEntryList( &Poll->ListEntry );
|
||||
KeCancelTimer( &Poll->Timer );
|
||||
|
||||
if( NT_SUCCESS(Status) ) {
|
||||
FCB = FileObject->FsContext;
|
||||
/* Check select bits */
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
|
||||
ExFreePool( Poll );
|
||||
|
||||
if( !SocketAcquireStateLock( FCB ) ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Failed to get a socket state\n"));
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
} else {
|
||||
AFD_DbgPrint(MID_TRACE,("Got a socket state\n"));
|
||||
Status = STATUS_SUCCESS;
|
||||
HandleArray[i].Status =
|
||||
FCB->PollState & HandleArray[i].Events;
|
||||
if( HandleArray[i].Status ) ShouldReturnNow = TRUE;
|
||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
||||
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
|
||||
SocketStateUnlock( FCB );
|
||||
AFD_DbgPrint(MID_TRACE,("Unlocked\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||
}
|
||||
|
||||
if( !NT_SUCCESS(Status) || ShouldReturnNow ) return Status;
|
||||
else return STATUS_PENDING;
|
||||
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq,
|
||||
NTSTATUS Status, UINT Collected ) {
|
||||
PIRP Irp = Poll->Irp;
|
||||
AFD_DbgPrint(MID_TRACE,("Called (Status %x Events %d)\n",
|
||||
Status, Collected));
|
||||
Poll->Irp->IoStatus.Status = Status;
|
||||
Poll->Irp->IoStatus.Information = Collected;
|
||||
CopyBackStatus( PollReq->Handles,
|
||||
PollReq->HandleCount );
|
||||
UnlockHandles( PollReq->InternalUse, PollReq->HandleCount );
|
||||
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||
RemoveEntryList( &Poll->ListEntry );
|
||||
RemoveSelect( Poll );
|
||||
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||
}
|
||||
|
||||
VOID SelectTimeout( PKDPC Dpc,
|
||||
|
@ -86,33 +64,31 @@ VOID SelectTimeout( PKDPC Dpc,
|
|||
PVOID SystemArgument2 ) {
|
||||
PAFD_ACTIVE_POLL Poll = DeferredContext;
|
||||
PAFD_POLL_INFO PollReq;
|
||||
PAFD_DEVICE_EXTENSION DeviceExt;
|
||||
PIRP Irp;
|
||||
KIRQL OldIrql;
|
||||
PAFD_DEVICE_EXTENSION DeviceExt;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||
|
||||
Irp = Poll->Irp;
|
||||
DeviceExt = Poll->DeviceExt;
|
||||
|
||||
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||
RemoveEntryList( &Poll->ListEntry );
|
||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||
|
||||
ExFreePool( Poll );
|
||||
|
||||
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
||||
|
||||
Irp->IoStatus.Status = STATUS_TIMEOUT;
|
||||
Irp->IoStatus.Information = -1;
|
||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||
SignalSocket( Poll, PollReq, STATUS_TIMEOUT, 0 );
|
||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||
|
||||
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
||||
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp ) {
|
||||
NTSTATUS Status = STATUS_NO_MEMORY;
|
||||
PAFD_FCB FCB;
|
||||
PFILE_OBJECT FileObject;
|
||||
PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||
PAFD_ACTIVE_POLL Poll = NULL;
|
||||
|
@ -120,115 +96,122 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
|||
UINT AllocSize =
|
||||
CopySize + sizeof(AFD_ACTIVE_POLL) - sizeof(AFD_POLL_INFO);
|
||||
KIRQL OldIrql;
|
||||
UINT HandlesSignalled;
|
||||
UINT i, Signalled = 0;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n",
|
||||
PollReq->HandleCount,
|
||||
(INT)(PollReq->Timeout.QuadPart * -1)));
|
||||
(INT)(PollReq->Timeout.QuadPart)));
|
||||
|
||||
Status = ScanForImmediateTrigger( PollReq->Handles,
|
||||
PollReq->HandleCount,
|
||||
&HandlesSignalled );
|
||||
|
||||
if( Status == STATUS_PENDING ) {
|
||||
Poll = ExAllocatePool( NonPagedPool, AllocSize );
|
||||
|
||||
if( Poll ) {
|
||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||
|
||||
KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
|
||||
(PKDEFERRED_ROUTINE)SelectTimeout,
|
||||
Poll );
|
||||
PollReq->Timeout.QuadPart *= -1;
|
||||
/* Negative values are relative */
|
||||
KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
|
||||
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
|
||||
|
||||
Poll->Irp = Irp;
|
||||
Poll->DeviceExt = DeviceExt;
|
||||
PollReq->InternalUse =
|
||||
LockHandles( PollReq->Handles, PollReq->HandleCount );
|
||||
|
||||
InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
|
||||
Status = STATUS_PENDING;
|
||||
|
||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||
} else Status = STATUS_NO_MEMORY;
|
||||
} else if( Status == STATUS_SUCCESS ) {
|
||||
CopyBackStatus( PollReq->Handles,
|
||||
PollReq->HandleCount );
|
||||
} else {
|
||||
ZeroEvents( PollReq->Handles,
|
||||
PollReq->HandleCount );
|
||||
if( !PollReq->InternalUse ) {
|
||||
Irp->IoStatus.Status = STATUS_NO_MEMORY;
|
||||
Irp->IoStatus.Information = -1;
|
||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
ZeroEvents( PollReq->Handles,
|
||||
PollReq->HandleCount );
|
||||
|
||||
Poll = ExAllocatePool( NonPagedPool, AllocSize );
|
||||
|
||||
if( Poll ) {
|
||||
Poll->Irp = Irp;
|
||||
Poll->DeviceExt = DeviceExt;
|
||||
|
||||
KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
|
||||
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
|
||||
|
||||
KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
|
||||
(PKDEFERRED_ROUTINE)SelectTimeout,
|
||||
Poll );
|
||||
|
||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||
InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
|
||||
|
||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
||||
if( !PollReq->InternalUse[i].Handle ) continue;
|
||||
|
||||
FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
|
||||
FCB = FileObject->FsContext;
|
||||
|
||||
if( (FCB->PollState & AFD_EVENT_CLOSE) ||
|
||||
(PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
|
||||
PollReq->InternalUse[i].Handle = 0;
|
||||
PollReq->Handles[i].Events = 0;
|
||||
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
|
||||
Signalled++;
|
||||
} else {
|
||||
PollReq->Handles[i].Status =
|
||||
PollReq->Handles[i].Events & FCB->PollState;
|
||||
if( PollReq->Handles[i].Status ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n",
|
||||
FCB, FCB->PollState));
|
||||
Signalled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Signalled ) {
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Signalled;
|
||||
SignalSocket( Poll, PollReq, Status, Signalled );
|
||||
} else {
|
||||
Status = STATUS_PENDING;
|
||||
IoMarkIrpPending( Irp );
|
||||
}
|
||||
|
||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||
} else Status = STATUS_NO_MEMORY;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
||||
|
||||
if( Status == STATUS_PENDING )
|
||||
IoMarkIrpPending( Irp );
|
||||
else {
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = HandlesSignalled;
|
||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq, UINT i ) {
|
||||
/* One of the files was destroyed. We return now with error. */
|
||||
Poll->Irp->IoStatus.Status = STATUS_SUCCESS; /* XXX REVISIT */
|
||||
Poll->Irp->IoStatus.Information = 1;
|
||||
CopyBackStatus( PollReq->Handles,
|
||||
PollReq->HandleCount );
|
||||
IoCompleteRequest( Poll->Irp, IO_NETWORK_INCREMENT );
|
||||
}
|
||||
|
||||
/* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */
|
||||
BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
|
||||
UINT i;
|
||||
NTSTATUS Status;
|
||||
PFILE_OBJECT TargetFile;
|
||||
PAFD_FCB FCB;
|
||||
UINT Signalled = 0;
|
||||
PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
|
||||
|
||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
||||
Status =
|
||||
ObReferenceObjectByHandle
|
||||
( (PVOID)PollReq->Handles[i].Handle,
|
||||
FILE_ALL_ACCESS,
|
||||
NULL,
|
||||
KernelMode,
|
||||
(PVOID*)&TargetFile,
|
||||
NULL );
|
||||
if( !PollReq->InternalUse[i].Handle ) continue;
|
||||
|
||||
FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
|
||||
FCB = FileObject->FsContext;
|
||||
|
||||
if( !NT_SUCCESS(Status) ) {
|
||||
if( (FCB->PollState & AFD_EVENT_CLOSE) ||
|
||||
(PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
|
||||
PollReq->InternalUse[i].Handle = 0;
|
||||
PollReq->Handles[i].Events = 0;
|
||||
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
|
||||
SignalSocket( Poll, PollReq, i );
|
||||
return TRUE;
|
||||
Signalled++;
|
||||
} else {
|
||||
FCB = FileObject->FsContext;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
|
||||
|
||||
if( !SocketAcquireStateLock( FCB ) ) {
|
||||
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
|
||||
SignalSocket( Poll, PollReq, i );
|
||||
} else {
|
||||
PollReq->Handles[i].Status =
|
||||
PollReq->Handles[i].Events & FCB->PollState;
|
||||
if( PollReq->Handles[i].Status )
|
||||
SignalSocket( Poll, PollReq, i );
|
||||
SocketStateUnlock( FCB );
|
||||
PollReq->Handles[i].Status =
|
||||
PollReq->Handles[i].Events & FCB->PollState;
|
||||
if( PollReq->Handles[i].Status ) {
|
||||
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n",
|
||||
FCB, FCB->PollState));
|
||||
Signalled++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return Signalled ? 1 : 0;
|
||||
}
|
||||
|
||||
VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
||||
PAFD_ACTIVE_POLL Poll = NULL;
|
||||
PLIST_ENTRY ThePollEnt = NULL;
|
||||
KIRQL OldIrql;
|
||||
PAFD_POLL_INFO PollReq;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n",
|
||||
DeviceExt, FileObject));
|
||||
|
@ -239,9 +222,13 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
|||
|
||||
while( ThePollEnt != &DeviceExt->Polls ) {
|
||||
Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry );
|
||||
PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
||||
AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
|
||||
|
||||
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
||||
ThePollEnt = ThePollEnt->Flink;
|
||||
RemoveEntryList( &Poll->ListEntry );
|
||||
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
||||
SignalSocket( Poll, PollReq, STATUS_SUCCESS, 1 );
|
||||
} else
|
||||
ThePollEnt = ThePollEnt->Flink;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: afd.h,v 1.23 2004/11/15 18:24:57 arty Exp $
|
||||
/* $Id: afd.h,v 1.24 2004/11/17 05:17:22 arty Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -186,6 +186,8 @@ NTSTATUS DDKAPI UnlockAndMaybeComplete
|
|||
BOOL ShouldUnlockIrp );
|
||||
VOID SocketStateUnlock( PAFD_FCB FCB );
|
||||
NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp );
|
||||
PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
|
||||
VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
|
||||
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||
VOID SocketCalloutEnter( PAFD_FCB FCB );
|
||||
|
|
|
@ -160,7 +160,6 @@ VOID DeleteAddress(PADDRESS_FILE AddrFile)
|
|||
/* Abort the request and free its resources */
|
||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
|
||||
ExFreePool(ReceiveRequest);
|
||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
CurrentEntry = NextEntry;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
#include "precomp.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
|
||||
#ifndef NDEBUG
|
||||
DWORD DebugTraceLevel = 0x7fffffff;
|
||||
|
|
|
@ -413,113 +413,142 @@ WSPSelect(
|
|||
struct timeval *timeout,
|
||||
LPINT lpErrno)
|
||||
{
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
PAFD_POLL_INFO PollInfo;
|
||||
NTSTATUS Status;
|
||||
ULONG HandleCount;
|
||||
ULONG PollBufferSize;
|
||||
LARGE_INTEGER uSec;
|
||||
PVOID PollBuffer;
|
||||
ULONG i, j = 0;
|
||||
HANDLE SockEvent;
|
||||
IO_STATUS_BLOCK IOSB;
|
||||
PAFD_POLL_INFO PollInfo;
|
||||
NTSTATUS Status;
|
||||
ULONG HandleCount, OutCount = 0;
|
||||
ULONG PollBufferSize;
|
||||
LARGE_INTEGER uSec;
|
||||
PVOID PollBuffer;
|
||||
ULONG i, j = 0, x;
|
||||
HANDLE SockEvent;
|
||||
|
||||
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
|
||||
NULL, 1, FALSE );
|
||||
|
||||
if( !NT_SUCCESS(Status) ) return -1;
|
||||
|
||||
/* Find out how many sockets we have, and how large the buffer needs
|
||||
* to be */
|
||||
|
||||
HandleCount =
|
||||
( readfds ? readfds->fd_count : 0 ) +
|
||||
( writefds ? writefds->fd_count : 0 ) +
|
||||
( exceptfds ? exceptfds->fd_count : 0 );
|
||||
PollBufferSize = sizeof(*PollInfo) +
|
||||
(HandleCount * sizeof(AFD_HANDLE));
|
||||
|
||||
/* Allocate */
|
||||
PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
|
||||
PollInfo = (PAFD_POLL_INFO)PollBuffer;
|
||||
|
||||
RtlZeroMemory( PollInfo, PollBufferSize );
|
||||
|
||||
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
|
||||
NULL, 1, FALSE );
|
||||
|
||||
if( !NT_SUCCESS(Status) ) return -1;
|
||||
|
||||
/* Find out how many sockets we have, and how large the buffer needs to be */
|
||||
HandleCount = ( readfds ? readfds->fd_count : 0 ) +
|
||||
( writefds ? writefds->fd_count : 0 ) +
|
||||
( exceptfds ? exceptfds->fd_count : 0 );
|
||||
PollBufferSize = sizeof(*PollInfo) + (HandleCount * sizeof(AFD_HANDLE));
|
||||
|
||||
/* Allocate */
|
||||
PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
|
||||
PollInfo = (PAFD_POLL_INFO)PollBuffer;
|
||||
|
||||
/* Convert Timeout to NT Format */
|
||||
if (timeout == NULL) {
|
||||
PollInfo->Timeout.u.LowPart = -1;
|
||||
PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
|
||||
} else {
|
||||
PollInfo->Timeout = RtlEnlargedIntegerMultiply(timeout->tv_sec, -10000000);
|
||||
uSec = RtlEnlargedIntegerMultiply(timeout->tv_usec, -10);
|
||||
PollInfo->Timeout.QuadPart += uSec.QuadPart;
|
||||
/* Convert Timeout to NT Format */
|
||||
if (timeout == NULL) {
|
||||
PollInfo->Timeout.u.LowPart = -1;
|
||||
PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
|
||||
} else {
|
||||
PollInfo->Timeout = RtlEnlargedIntegerMultiply
|
||||
((timeout->tv_sec * 1000) + timeout->tv_usec, -10000);
|
||||
PollInfo->Timeout.QuadPart += uSec.QuadPart;
|
||||
}
|
||||
|
||||
/* Number of handles for AFD to Check */
|
||||
PollInfo->HandleCount = HandleCount;
|
||||
PollInfo->InternalUse = 0;
|
||||
|
||||
if (readfds != NULL) {
|
||||
for (i = 0; i < readfds->fd_count; i++, j++) {
|
||||
PollInfo->Handles[j].Handle = readfds->fd_array[i];
|
||||
PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
|
||||
}
|
||||
}
|
||||
if (writefds != NULL) {
|
||||
for (i = 0; i < writefds->fd_count; i++, j++) {
|
||||
PollInfo->Handles[j].Handle = writefds->fd_array[i];
|
||||
PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
|
||||
}
|
||||
|
||||
/* Number of handles for AFD to Check */
|
||||
PollInfo->HandleCount = HandleCount;
|
||||
PollInfo->Unknown = 0;
|
||||
|
||||
if (readfds != NULL) {
|
||||
for (i = 0; i < readfds->fd_count; i++, j++) {
|
||||
PollInfo->Handles[j].Handle = readfds->fd_array[i];
|
||||
PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
|
||||
}
|
||||
} else if (writefds != NULL) {
|
||||
for (i = 0; i < writefds->fd_count; i++, j++) {
|
||||
PollInfo->Handles[j].Handle = writefds->fd_array[i];
|
||||
PollInfo->Handles[j].Events = AFD_EVENT_SEND;
|
||||
}
|
||||
|
||||
} else if (exceptfds != NULL) {
|
||||
for (i = 0; i < exceptfds->fd_count; i++, j++) {
|
||||
PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
|
||||
PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
|
||||
}
|
||||
}
|
||||
if (exceptfds != NULL) {
|
||||
for (i = 0; i < exceptfds->fd_count; i++, j++) {
|
||||
PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
|
||||
PollInfo->Handles[j].Events |=
|
||||
AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send IOCTL */
|
||||
Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle,
|
||||
SockEvent,
|
||||
NULL,
|
||||
NULL,
|
||||
&IOSB,
|
||||
IOCTL_AFD_SELECT,
|
||||
PollInfo,
|
||||
PollBufferSize,
|
||||
PollInfo,
|
||||
PollBufferSize);
|
||||
|
||||
/* Send IOCTL */
|
||||
Status = NtDeviceIoControlFile( (HANDLE)Sockets[0]->Handle,
|
||||
SockEvent,
|
||||
NULL,
|
||||
NULL,
|
||||
&IOSB,
|
||||
IOCTL_AFD_SELECT,
|
||||
PollInfo,
|
||||
PollBufferSize,
|
||||
PollInfo,
|
||||
PollBufferSize);
|
||||
|
||||
/* Wait for Completition */
|
||||
if (Status == STATUS_PENDING) {
|
||||
WaitForSingleObject(SockEvent, 0);
|
||||
AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status));
|
||||
|
||||
/* Wait for Completition */
|
||||
if (Status == STATUS_PENDING) {
|
||||
WaitForSingleObject(SockEvent, 0);
|
||||
}
|
||||
|
||||
/* Clear the Structures */
|
||||
if( readfds ) FD_ZERO(readfds);
|
||||
if( writefds ) FD_ZERO(writefds);
|
||||
if( exceptfds ) FD_ZERO(exceptfds);
|
||||
|
||||
/* Loop through return structure */
|
||||
HandleCount = PollInfo->HandleCount;
|
||||
|
||||
/* Return in FDSET Format */
|
||||
for (i = 0; i < HandleCount; i++) {
|
||||
for(x = 1; x; x<<=1) {
|
||||
switch (PollInfo->Handles[i].Events & x) {
|
||||
case AFD_EVENT_RECEIVE:
|
||||
case AFD_EVENT_DISCONNECT:
|
||||
case AFD_EVENT_ABORT:
|
||||
case AFD_EVENT_ACCEPT:
|
||||
case AFD_EVENT_CLOSE:
|
||||
AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
|
||||
PollInfo->Handles[i].Events,
|
||||
PollInfo->Handles[i].Handle));
|
||||
OutCount++;
|
||||
if( readfds ) FD_SET(PollInfo->Handles[i].Handle, readfds);
|
||||
case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
|
||||
AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
|
||||
PollInfo->Handles[i].Events,
|
||||
PollInfo->Handles[i].Handle));
|
||||
OutCount++;
|
||||
if( writefds ) FD_SET(PollInfo->Handles[i].Handle, writefds);
|
||||
break;
|
||||
|
||||
case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
|
||||
AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
|
||||
PollInfo->Handles[i].Events,
|
||||
PollInfo->Handles[i].Handle));
|
||||
OutCount++;
|
||||
if( exceptfds ) FD_SET(PollInfo->Handles[i].Handle, exceptfds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the Structures */
|
||||
readfds ? FD_ZERO(readfds) : 0;
|
||||
writefds ? FD_ZERO(writefds) : 0;
|
||||
exceptfds ? FD_ZERO(exceptfds) : 0;
|
||||
NtClose( SockEvent );
|
||||
switch( IOSB.Status ) {
|
||||
case STATUS_SUCCESS:
|
||||
case STATUS_TIMEOUT: *lpErrno = 0; break;
|
||||
default: *lpErrno = WSAEINVAL;
|
||||
}
|
||||
|
||||
/* Loop through return structure */
|
||||
HandleCount = PollInfo->HandleCount;
|
||||
|
||||
/* Return in FDSET Format */
|
||||
for (i = 0; i < HandleCount; i++) {
|
||||
switch (PollInfo->Handles[i].Events) {
|
||||
|
||||
case AFD_EVENT_RECEIVE:
|
||||
case AFD_EVENT_DISCONNECT:
|
||||
case AFD_EVENT_ABORT:
|
||||
case AFD_EVENT_ACCEPT:
|
||||
case AFD_EVENT_CLOSE:
|
||||
FD_SET(PollInfo->Handles[i].Handle, readfds);
|
||||
break;
|
||||
|
||||
case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
|
||||
FD_SET(PollInfo->Handles[i].Handle, writefds);
|
||||
break;
|
||||
|
||||
case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
|
||||
FD_SET(PollInfo->Handles[i].Handle, exceptfds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NtClose( SockEvent );
|
||||
|
||||
return 0;
|
||||
AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount));
|
||||
|
||||
return OutCount;
|
||||
}
|
||||
|
||||
SOCKET
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.17 2004/10/23 21:05:11 chorns Exp $
|
||||
# $Id: makefile,v 1.18 2004/11/17 05:17:21 arty Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
|
@ -19,7 +19,6 @@ TARGET_CFLAGS = \
|
|||
-fno-builtin \
|
||||
-DUNICODE \
|
||||
-DLE \
|
||||
-DDBG \
|
||||
-D__USE_W32API
|
||||
|
||||
# require os code to explicitly request A/W version of structs/functions
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <roscfg.h>
|
||||
#include <w32api.h>
|
||||
#include <ws2_32.h>
|
||||
#include <catalog.h>
|
||||
|
@ -18,6 +19,7 @@
|
|||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = MIN_TRACE;
|
||||
//DWORD DebugTraceLevel = MAX_TRACE;
|
||||
//DWORD DebugTraceLevel = DEBUG_ULTRA;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
@ -339,6 +341,7 @@ select(
|
|||
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
WS_DbgPrint(MID_TRACE,("Not initialized\n"));
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -348,33 +351,48 @@ select(
|
|||
if ((readfds != NULL) && (readfds->fd_count > 0)) {
|
||||
if (!ReferenceProviderByHandle((HANDLE)readfds->fd_array[0], &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
WS_DbgPrint(MID_TRACE,("No provider (read)\n"));
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
} else if ((writefds != NULL) && (writefds->fd_count > 0)) {
|
||||
if (!ReferenceProviderByHandle((HANDLE)writefds->fd_array[0], &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
WS_DbgPrint(MID_TRACE,("No provider (write)\n"));
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
} else if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) {
|
||||
if (!ReferenceProviderByHandle((HANDLE)exceptfds->fd_array[0], &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
WS_DbgPrint(MID_TRACE,("No provider (err)\n"));
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
#if 0 /* XXX empty select is not an error */
|
||||
} else {
|
||||
WSASetLastError(WSAEINVAL);
|
||||
return SOCKET_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
Count = Provider->ProcTable.lpWSPSelect(
|
||||
nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
||||
|
||||
DereferenceProviderByPointer(Provider);
|
||||
|
||||
if (Errno != NO_ERROR) {
|
||||
WSASetLastError(Errno);
|
||||
return SOCKET_ERROR;
|
||||
if( !Provider ) {
|
||||
if( timeout ) {
|
||||
WS_DbgPrint(MID_TRACE,("Select: used as timer\n"));
|
||||
Sleep( timeout->tv_sec * 1000 + (timeout->tv_usec / 1000) );
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
WS_DbgPrint(MID_TRACE,("Calling WSPSelect\n"));
|
||||
Count = Provider->ProcTable.lpWSPSelect(
|
||||
nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("[%x] Select: Count %d Errno %x\n",
|
||||
Provider, Count, Errno));
|
||||
|
||||
DereferenceProviderByPointer(Provider);
|
||||
|
||||
if (Errno != NO_ERROR) {
|
||||
WSASetLastError(Errno);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return Count;
|
||||
|
@ -630,6 +648,20 @@ WSAIoctl(
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
INT
|
||||
EXPORT
|
||||
__WSAFDIsSet(SOCKET s, LPFD_SET set)
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < set->fd_count; i++ )
|
||||
if( set->fd_array[i] == s ) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
|
|
|
@ -636,23 +636,6 @@ WSACancelAsyncRequest(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
INT
|
||||
#if 0
|
||||
PASCAL FAR
|
||||
#else
|
||||
EXPORT
|
||||
#endif
|
||||
__WSAFDIsSet(SOCKET s, LPFD_SET set)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* WinSock Service Provider support functions */
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue