mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/lock.c
|
* FILE: drivers/net/afd/afd/lock.c
|
||||||
|
@ -114,6 +114,40 @@ VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count, BOOL Address ) {
|
||||||
ExFreePool( Buf );
|
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 */
|
/* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
|
||||||
UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
|
UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/main.c
|
* 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));
|
AFD_DbgPrint(MID_TRACE,("FCB %x\n", FCB));
|
||||||
|
|
||||||
FileObject->FsContext = NULL;
|
FileObject->FsContext = NULL;
|
||||||
|
FCB->PollState |= AFD_EVENT_CLOSE;
|
||||||
|
PollReeval( FCB->DeviceExt, FileObject );
|
||||||
|
|
||||||
DestroySocket( FCB );
|
DestroySocket( FCB );
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/read.c
|
* FILE: drivers/net/afd/afd/read.c
|
||||||
|
@ -416,7 +416,8 @@ PacketSocketRecvComplete(
|
||||||
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
|
AFD_DbgPrint(MID_TRACE,("Signalling\n"));
|
||||||
FCB->PollState |= AFD_EVENT_RECEIVE;
|
FCB->PollState |= AFD_EVENT_RECEIVE;
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
}
|
} else
|
||||||
|
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 */
|
||||||
|
@ -483,9 +484,6 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
return UnlockAndMaybeComplete
|
return UnlockAndMaybeComplete
|
||||||
( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
|
( FCB, Status, Irp, RecvReq->BufferArray[0].len, NULL, TRUE );
|
||||||
} else {
|
} else {
|
||||||
if( IsListEmpty( &FCB->DatagramList ) )
|
|
||||||
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
|
||||||
|
|
||||||
Status = SatisfyPacketRecvRequest
|
Status = SatisfyPacketRecvRequest
|
||||||
( FCB, Irp, DatagramRecv,
|
( FCB, Irp, DatagramRecv,
|
||||||
(PUINT)&Irp->IoStatus.Information );
|
(PUINT)&Irp->IoStatus.Information );
|
||||||
|
@ -493,10 +491,12 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
|
( FCB, Status, Irp, Irp->IoStatus.Information, NULL, TRUE );
|
||||||
}
|
}
|
||||||
} else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
|
} else if( RecvReq->AfdFlags & AFD_IMMEDIATE ) {
|
||||||
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
|
||||||
Status = STATUS_CANT_WAIT;
|
Status = STATUS_CANT_WAIT;
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, TRUE );
|
||||||
} else {
|
} else {
|
||||||
|
FCB->PollState &= ~AFD_EVENT_RECEIVE;
|
||||||
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: drivers/net/afd/afd/select.c
|
* FILE: drivers/net/afd/afd/select.c
|
||||||
|
@ -26,58 +26,36 @@ 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].Events = 0;
|
|
||||||
HandleArray[i].Status = 0;
|
HandleArray[i].Status = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
VOID RemoveSelect( PAFD_ACTIVE_POLL Poll ) {
|
||||||
ScanForImmediateTrigger( PAFD_HANDLE HandleArray,
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
UINT HandleCount,
|
|
||||||
PUINT HandlesSet ) {
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
PAFD_FCB FCB;
|
|
||||||
UINT i;
|
|
||||||
BOOLEAN ShouldReturnNow = FALSE;
|
|
||||||
|
|
||||||
for( i = 0; i < HandleCount && NT_SUCCESS(Status); i++ ) {
|
RemoveEntryList( &Poll->ListEntry );
|
||||||
HandleArray[i].Status = 0;
|
KeCancelTimer( &Poll->Timer );
|
||||||
Status =
|
|
||||||
ObReferenceObjectByHandle
|
|
||||||
( (PVOID)HandleArray[i].Handle,
|
|
||||||
FILE_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
KernelMode,
|
|
||||||
(PVOID*)&FileObject,
|
|
||||||
NULL );
|
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
ExFreePool( Poll );
|
||||||
FCB = FileObject->FsContext;
|
|
||||||
/* Check select bits */
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
|
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||||
|
}
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) {
|
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq,
|
||||||
AFD_DbgPrint(MID_TRACE,("Failed to get a socket state\n"));
|
NTSTATUS Status, UINT Collected ) {
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
PIRP Irp = Poll->Irp;
|
||||||
} else {
|
AFD_DbgPrint(MID_TRACE,("Called (Status %x Events %d)\n",
|
||||||
AFD_DbgPrint(MID_TRACE,("Got a socket state\n"));
|
Status, Collected));
|
||||||
Status = STATUS_SUCCESS;
|
Poll->Irp->IoStatus.Status = Status;
|
||||||
HandleArray[i].Status =
|
Poll->Irp->IoStatus.Information = Collected;
|
||||||
FCB->PollState & HandleArray[i].Events;
|
CopyBackStatus( PollReq->Handles,
|
||||||
if( HandleArray[i].Status ) ShouldReturnNow = TRUE;
|
PollReq->HandleCount );
|
||||||
ObDereferenceObject( (PVOID)HandleArray[i].Handle );
|
UnlockHandles( PollReq->InternalUse, PollReq->HandleCount );
|
||||||
AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
|
AFD_DbgPrint(MID_TRACE,("Completing\n"));
|
||||||
SocketStateUnlock( FCB );
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
AFD_DbgPrint(MID_TRACE,("Unlocked\n"));
|
RemoveEntryList( &Poll->ListEntry );
|
||||||
}
|
RemoveSelect( Poll );
|
||||||
}
|
AFD_DbgPrint(MID_TRACE,("Done\n"));
|
||||||
}
|
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) || ShouldReturnNow ) return Status;
|
|
||||||
else return STATUS_PENDING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID SelectTimeout( PKDPC Dpc,
|
VOID SelectTimeout( PKDPC Dpc,
|
||||||
|
@ -86,33 +64,31 @@ VOID SelectTimeout( PKDPC Dpc,
|
||||||
PVOID SystemArgument2 ) {
|
PVOID SystemArgument2 ) {
|
||||||
PAFD_ACTIVE_POLL Poll = DeferredContext;
|
PAFD_ACTIVE_POLL Poll = DeferredContext;
|
||||||
PAFD_POLL_INFO PollReq;
|
PAFD_POLL_INFO PollReq;
|
||||||
PAFD_DEVICE_EXTENSION DeviceExt;
|
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
PAFD_DEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
|
||||||
Irp = Poll->Irp;
|
Irp = Poll->Irp;
|
||||||
DeviceExt = Poll->DeviceExt;
|
DeviceExt = Poll->DeviceExt;
|
||||||
|
|
||||||
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
|
||||||
RemoveEntryList( &Poll->ListEntry );
|
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
|
||||||
|
|
||||||
ExFreePool( Poll );
|
|
||||||
|
|
||||||
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_TIMEOUT;
|
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||||
Irp->IoStatus.Information = -1;
|
SignalSocket( Poll, PollReq, STATUS_TIMEOUT, 0 );
|
||||||
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
|
|
||||||
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PIO_STACK_LOCATION IrpSp ) {
|
PIO_STACK_LOCATION IrpSp ) {
|
||||||
NTSTATUS Status = STATUS_NO_MEMORY;
|
NTSTATUS Status = STATUS_NO_MEMORY;
|
||||||
|
PAFD_FCB FCB;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer;
|
PAFD_POLL_INFO PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||||
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
PAFD_ACTIVE_POLL Poll = NULL;
|
PAFD_ACTIVE_POLL Poll = NULL;
|
||||||
|
@ -120,115 +96,122 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
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 HandlesSignalled;
|
UINT i, Signalled = 0;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n",
|
AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n",
|
||||||
PollReq->HandleCount,
|
PollReq->HandleCount,
|
||||||
(INT)(PollReq->Timeout.QuadPart * -1)));
|
(INT)(PollReq->Timeout.QuadPart)));
|
||||||
|
|
||||||
Status = ScanForImmediateTrigger( PollReq->Handles,
|
PollReq->InternalUse =
|
||||||
PollReq->HandleCount,
|
LockHandles( PollReq->Handles, PollReq->HandleCount );
|
||||||
&HandlesSignalled );
|
|
||||||
|
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 );
|
||||||
|
|
||||||
if( Status == STATUS_PENDING ) {
|
|
||||||
Poll = ExAllocatePool( NonPagedPool, AllocSize );
|
Poll = ExAllocatePool( NonPagedPool, AllocSize );
|
||||||
|
|
||||||
if( Poll ) {
|
if( Poll ) {
|
||||||
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
Poll->Irp = Irp;
|
||||||
|
Poll->DeviceExt = DeviceExt;
|
||||||
|
|
||||||
|
KeInitializeTimerEx( &Poll->Timer, NotificationTimer );
|
||||||
|
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
|
||||||
|
|
||||||
KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
|
KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc,
|
||||||
(PKDEFERRED_ROUTINE)SelectTimeout,
|
(PKDEFERRED_ROUTINE)SelectTimeout,
|
||||||
Poll );
|
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;
|
|
||||||
|
|
||||||
|
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
|
||||||
InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );
|
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;
|
Status = STATUS_PENDING;
|
||||||
|
IoMarkIrpPending( Irp );
|
||||||
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
|
||||||
} else Status = STATUS_NO_MEMORY;
|
} else Status = STATUS_NO_MEMORY;
|
||||||
} else if( Status == STATUS_SUCCESS ) {
|
|
||||||
CopyBackStatus( PollReq->Handles,
|
|
||||||
PollReq->HandleCount );
|
|
||||||
} else {
|
|
||||||
ZeroEvents( PollReq->Handles,
|
|
||||||
PollReq->HandleCount );
|
|
||||||
}
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq, UINT i ) {
|
/* * * NOTE ALWAYS CALLED AT DISPATCH_LEVEL * * */
|
||||||
/* One of the files was destroyed. We return now with error. */
|
|
||||||
Poll->Irp->IoStatus.Status = STATUS_SUCCESS; /* XXX REVISIT */
|
|
||||||
Poll->Irp->IoStatus.Information = 1;
|
|
||||||
CopyBackStatus( PollReq->Handles,
|
|
||||||
PollReq->HandleCount );
|
|
||||||
IoCompleteRequest( Poll->Irp, IO_NETWORK_INCREMENT );
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
|
BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject ) {
|
||||||
UINT i;
|
UINT i;
|
||||||
NTSTATUS Status;
|
|
||||||
PFILE_OBJECT TargetFile;
|
|
||||||
PAFD_FCB FCB;
|
PAFD_FCB FCB;
|
||||||
|
UINT Signalled = 0;
|
||||||
PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
PAFD_POLL_INFO PollReq = Poll->Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );
|
||||||
Status =
|
|
||||||
ObReferenceObjectByHandle
|
|
||||||
( (PVOID)PollReq->Handles[i].Handle,
|
|
||||||
FILE_ALL_ACCESS,
|
|
||||||
NULL,
|
|
||||||
KernelMode,
|
|
||||||
(PVOID*)&TargetFile,
|
|
||||||
NULL );
|
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) ) {
|
for( i = 0; i < PollReq->HandleCount; i++ ) {
|
||||||
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
|
if( !PollReq->InternalUse[i].Handle ) continue;
|
||||||
SignalSocket( Poll, PollReq, i );
|
|
||||||
return TRUE;
|
FileObject = (PFILE_OBJECT)PollReq->InternalUse[i].Handle;
|
||||||
} else {
|
|
||||||
FCB = FileObject->FsContext;
|
FCB = FileObject->FsContext;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Locking socket state\n"));
|
if( (FCB->PollState & AFD_EVENT_CLOSE) ||
|
||||||
|
(PollReq->Handles[i].Status & AFD_EVENT_CLOSE) ) {
|
||||||
if( !SocketAcquireStateLock( FCB ) ) {
|
PollReq->InternalUse[i].Handle = 0;
|
||||||
|
PollReq->Handles[i].Events = 0;
|
||||||
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
|
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
|
||||||
SignalSocket( Poll, PollReq, i );
|
Signalled++;
|
||||||
} else {
|
} else {
|
||||||
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 ) {
|
||||||
SignalSocket( Poll, PollReq, i );
|
AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n",
|
||||||
SocketStateUnlock( FCB );
|
FCB, FCB->PollState));
|
||||||
|
Signalled++;
|
||||||
}
|
}
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
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;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
PAFD_POLL_INFO PollReq;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n",
|
AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n",
|
||||||
DeviceExt, FileObject));
|
DeviceExt, FileObject));
|
||||||
|
@ -239,9 +222,13 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) {
|
||||||
|
|
||||||
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;
|
||||||
|
AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll));
|
||||||
|
|
||||||
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
if( UpdatePollWithFCB( Poll, FileObject ) ) {
|
||||||
ThePollEnt = ThePollEnt->Flink;
|
ThePollEnt = ThePollEnt->Flink;
|
||||||
RemoveEntryList( &Poll->ListEntry );
|
AFD_DbgPrint(MID_TRACE,("Signalling socket\n"));
|
||||||
|
SignalSocket( Poll, PollReq, STATUS_SUCCESS, 1 );
|
||||||
} else
|
} else
|
||||||
ThePollEnt = ThePollEnt->Flink;
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -186,6 +186,8 @@ NTSTATUS DDKAPI UnlockAndMaybeComplete
|
||||||
BOOL ShouldUnlockIrp );
|
BOOL ShouldUnlockIrp );
|
||||||
VOID SocketStateUnlock( PAFD_FCB FCB );
|
VOID SocketStateUnlock( PAFD_FCB FCB );
|
||||||
NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp );
|
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 );
|
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||||
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
|
||||||
VOID SocketCalloutEnter( PAFD_FCB FCB );
|
VOID SocketCalloutEnter( PAFD_FCB FCB );
|
||||||
|
|
|
@ -160,7 +160,6 @@ VOID DeleteAddress(PADDRESS_FILE AddrFile)
|
||||||
/* Abort the request and free its resources */
|
/* Abort the request and free its resources */
|
||||||
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||||
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
|
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
|
||||||
ExFreePool(ReceiveRequest);
|
|
||||||
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||||
CurrentEntry = NextEntry;
|
CurrentEntry = NextEntry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DWORD DebugTraceLevel = 0x7fffffff;
|
DWORD DebugTraceLevel = 0x7fffffff;
|
||||||
|
|
|
@ -416,11 +416,11 @@ WSPSelect(
|
||||||
IO_STATUS_BLOCK IOSB;
|
IO_STATUS_BLOCK IOSB;
|
||||||
PAFD_POLL_INFO PollInfo;
|
PAFD_POLL_INFO PollInfo;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG HandleCount;
|
ULONG HandleCount, OutCount = 0;
|
||||||
ULONG PollBufferSize;
|
ULONG PollBufferSize;
|
||||||
LARGE_INTEGER uSec;
|
LARGE_INTEGER uSec;
|
||||||
PVOID PollBuffer;
|
PVOID PollBuffer;
|
||||||
ULONG i, j = 0;
|
ULONG i, j = 0, x;
|
||||||
HANDLE SockEvent;
|
HANDLE SockEvent;
|
||||||
|
|
||||||
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
|
Status = NtCreateEvent( &SockEvent, GENERIC_READ | GENERIC_WRITE,
|
||||||
|
@ -428,45 +428,54 @@ WSPSelect(
|
||||||
|
|
||||||
if( !NT_SUCCESS(Status) ) return -1;
|
if( !NT_SUCCESS(Status) ) return -1;
|
||||||
|
|
||||||
/* Find out how many sockets we have, and how large the buffer needs to be */
|
/* Find out how many sockets we have, and how large the buffer needs
|
||||||
HandleCount = ( readfds ? readfds->fd_count : 0 ) +
|
* to be */
|
||||||
|
|
||||||
|
HandleCount =
|
||||||
|
( readfds ? readfds->fd_count : 0 ) +
|
||||||
( writefds ? writefds->fd_count : 0 ) +
|
( writefds ? writefds->fd_count : 0 ) +
|
||||||
( exceptfds ? exceptfds->fd_count : 0 );
|
( exceptfds ? exceptfds->fd_count : 0 );
|
||||||
PollBufferSize = sizeof(*PollInfo) + (HandleCount * sizeof(AFD_HANDLE));
|
PollBufferSize = sizeof(*PollInfo) +
|
||||||
|
(HandleCount * sizeof(AFD_HANDLE));
|
||||||
|
|
||||||
/* Allocate */
|
/* Allocate */
|
||||||
PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
|
PollBuffer = HeapAlloc(GlobalHeap, 0, PollBufferSize);
|
||||||
PollInfo = (PAFD_POLL_INFO)PollBuffer;
|
PollInfo = (PAFD_POLL_INFO)PollBuffer;
|
||||||
|
|
||||||
|
RtlZeroMemory( PollInfo, PollBufferSize );
|
||||||
|
|
||||||
/* Convert Timeout to NT Format */
|
/* Convert Timeout to NT Format */
|
||||||
if (timeout == NULL) {
|
if (timeout == NULL) {
|
||||||
PollInfo->Timeout.u.LowPart = -1;
|
PollInfo->Timeout.u.LowPart = -1;
|
||||||
PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
|
PollInfo->Timeout.u.HighPart = 0x7FFFFFFF;
|
||||||
} else {
|
} else {
|
||||||
PollInfo->Timeout = RtlEnlargedIntegerMultiply(timeout->tv_sec, -10000000);
|
PollInfo->Timeout = RtlEnlargedIntegerMultiply
|
||||||
uSec = RtlEnlargedIntegerMultiply(timeout->tv_usec, -10);
|
((timeout->tv_sec * 1000) + timeout->tv_usec, -10000);
|
||||||
PollInfo->Timeout.QuadPart += uSec.QuadPart;
|
PollInfo->Timeout.QuadPart += uSec.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Number of handles for AFD to Check */
|
/* Number of handles for AFD to Check */
|
||||||
PollInfo->HandleCount = HandleCount;
|
PollInfo->HandleCount = HandleCount;
|
||||||
PollInfo->Unknown = 0;
|
PollInfo->InternalUse = 0;
|
||||||
|
|
||||||
if (readfds != NULL) {
|
if (readfds != NULL) {
|
||||||
for (i = 0; i < readfds->fd_count; i++, j++) {
|
for (i = 0; i < readfds->fd_count; i++, j++) {
|
||||||
PollInfo->Handles[j].Handle = readfds->fd_array[i];
|
PollInfo->Handles[j].Handle = readfds->fd_array[i];
|
||||||
PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
|
PollInfo->Handles[j].Events = AFD_EVENT_RECEIVE | AFD_EVENT_DISCONNECT | AFD_EVENT_ABORT;
|
||||||
}
|
}
|
||||||
} else if (writefds != NULL) {
|
}
|
||||||
|
if (writefds != NULL) {
|
||||||
for (i = 0; i < writefds->fd_count; i++, j++) {
|
for (i = 0; i < writefds->fd_count; i++, j++) {
|
||||||
PollInfo->Handles[j].Handle = writefds->fd_array[i];
|
PollInfo->Handles[j].Handle = writefds->fd_array[i];
|
||||||
PollInfo->Handles[j].Events = AFD_EVENT_SEND;
|
PollInfo->Handles[j].Events |= AFD_EVENT_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (exceptfds != NULL) {
|
}
|
||||||
|
if (exceptfds != NULL) {
|
||||||
for (i = 0; i < exceptfds->fd_count; i++, j++) {
|
for (i = 0; i < exceptfds->fd_count; i++, j++) {
|
||||||
PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
|
PollInfo->Handles[j].Handle = exceptfds->fd_array[i];
|
||||||
PollInfo->Handles[j].Events = AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
|
PollInfo->Handles[j].Events |=
|
||||||
|
AFD_EVENT_OOB_RECEIVE | AFD_EVENT_CONNECT_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,44 +491,64 @@ WSPSelect(
|
||||||
PollInfo,
|
PollInfo,
|
||||||
PollBufferSize);
|
PollBufferSize);
|
||||||
|
|
||||||
|
AFD_DbgPrint(MID_TRACE,("DeviceIoControlFile => %x\n", Status));
|
||||||
|
|
||||||
/* Wait for Completition */
|
/* Wait for Completition */
|
||||||
if (Status == STATUS_PENDING) {
|
if (Status == STATUS_PENDING) {
|
||||||
WaitForSingleObject(SockEvent, 0);
|
WaitForSingleObject(SockEvent, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the Structures */
|
/* Clear the Structures */
|
||||||
readfds ? FD_ZERO(readfds) : 0;
|
if( readfds ) FD_ZERO(readfds);
|
||||||
writefds ? FD_ZERO(writefds) : 0;
|
if( writefds ) FD_ZERO(writefds);
|
||||||
exceptfds ? FD_ZERO(exceptfds) : 0;
|
if( exceptfds ) FD_ZERO(exceptfds);
|
||||||
|
|
||||||
/* Loop through return structure */
|
/* Loop through return structure */
|
||||||
HandleCount = PollInfo->HandleCount;
|
HandleCount = PollInfo->HandleCount;
|
||||||
|
|
||||||
/* Return in FDSET Format */
|
/* Return in FDSET Format */
|
||||||
for (i = 0; i < HandleCount; i++) {
|
for (i = 0; i < HandleCount; i++) {
|
||||||
switch (PollInfo->Handles[i].Events) {
|
for(x = 1; x; x<<=1) {
|
||||||
|
switch (PollInfo->Handles[i].Events & x) {
|
||||||
case AFD_EVENT_RECEIVE:
|
case AFD_EVENT_RECEIVE:
|
||||||
case AFD_EVENT_DISCONNECT:
|
case AFD_EVENT_DISCONNECT:
|
||||||
case AFD_EVENT_ABORT:
|
case AFD_EVENT_ABORT:
|
||||||
case AFD_EVENT_ACCEPT:
|
case AFD_EVENT_ACCEPT:
|
||||||
case AFD_EVENT_CLOSE:
|
case AFD_EVENT_CLOSE:
|
||||||
FD_SET(PollInfo->Handles[i].Handle, readfds);
|
AFD_DbgPrint(MID_TRACE,("Event %x on handle %x\n",
|
||||||
break;
|
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:
|
case AFD_EVENT_SEND: case AFD_EVENT_CONNECT:
|
||||||
FD_SET(PollInfo->Handles[i].Handle, writefds);
|
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;
|
break;
|
||||||
|
|
||||||
case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
|
case AFD_EVENT_OOB_RECEIVE: case AFD_EVENT_CONNECT_FAIL:
|
||||||
FD_SET(PollInfo->Handles[i].Handle, exceptfds);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NtClose( SockEvent );
|
NtClose( SockEvent );
|
||||||
|
switch( IOSB.Status ) {
|
||||||
|
case STATUS_SUCCESS:
|
||||||
|
case STATUS_TIMEOUT: *lpErrno = 0; break;
|
||||||
|
default: *lpErrno = WSAEINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
AFD_DbgPrint(MID_TRACE,("%d events\n", OutCount));
|
||||||
|
|
||||||
|
return OutCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET
|
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 = ../..
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ TARGET_CFLAGS = \
|
||||||
-fno-builtin \
|
-fno-builtin \
|
||||||
-DUNICODE \
|
-DUNICODE \
|
||||||
-DLE \
|
-DLE \
|
||||||
-DDBG \
|
|
||||||
-D__USE_W32API
|
-D__USE_W32API
|
||||||
|
|
||||||
# require os code to explicitly request A/W version of structs/functions
|
# require os code to explicitly request A/W version of structs/functions
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
* REVISIONS:
|
* REVISIONS:
|
||||||
* CSH 01/09-2000 Created
|
* CSH 01/09-2000 Created
|
||||||
*/
|
*/
|
||||||
|
#include <roscfg.h>
|
||||||
#include <w32api.h>
|
#include <w32api.h>
|
||||||
#include <ws2_32.h>
|
#include <ws2_32.h>
|
||||||
#include <catalog.h>
|
#include <catalog.h>
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
/* See debug.h for debug/trace constants */
|
/* See debug.h for debug/trace constants */
|
||||||
DWORD DebugTraceLevel = MIN_TRACE;
|
DWORD DebugTraceLevel = MIN_TRACE;
|
||||||
//DWORD DebugTraceLevel = MAX_TRACE;
|
//DWORD DebugTraceLevel = MAX_TRACE;
|
||||||
|
//DWORD DebugTraceLevel = DEBUG_ULTRA;
|
||||||
|
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
|
@ -339,6 +341,7 @@ select(
|
||||||
|
|
||||||
if (!WSAINITIALIZED) {
|
if (!WSAINITIALIZED) {
|
||||||
WSASetLastError(WSANOTINITIALISED);
|
WSASetLastError(WSANOTINITIALISED);
|
||||||
|
WS_DbgPrint(MID_TRACE,("Not initialized\n"));
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,27 +351,41 @@ select(
|
||||||
if ((readfds != NULL) && (readfds->fd_count > 0)) {
|
if ((readfds != NULL) && (readfds->fd_count > 0)) {
|
||||||
if (!ReferenceProviderByHandle((HANDLE)readfds->fd_array[0], &Provider)) {
|
if (!ReferenceProviderByHandle((HANDLE)readfds->fd_array[0], &Provider)) {
|
||||||
WSASetLastError(WSAENOTSOCK);
|
WSASetLastError(WSAENOTSOCK);
|
||||||
|
WS_DbgPrint(MID_TRACE,("No provider (read)\n"));
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
} else if ((writefds != NULL) && (writefds->fd_count > 0)) {
|
} else if ((writefds != NULL) && (writefds->fd_count > 0)) {
|
||||||
if (!ReferenceProviderByHandle((HANDLE)writefds->fd_array[0], &Provider)) {
|
if (!ReferenceProviderByHandle((HANDLE)writefds->fd_array[0], &Provider)) {
|
||||||
WSASetLastError(WSAENOTSOCK);
|
WSASetLastError(WSAENOTSOCK);
|
||||||
|
WS_DbgPrint(MID_TRACE,("No provider (write)\n"));
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
} else if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) {
|
} else if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) {
|
||||||
if (!ReferenceProviderByHandle((HANDLE)exceptfds->fd_array[0], &Provider)) {
|
if (!ReferenceProviderByHandle((HANDLE)exceptfds->fd_array[0], &Provider)) {
|
||||||
WSASetLastError(WSAENOTSOCK);
|
WSASetLastError(WSAENOTSOCK);
|
||||||
|
WS_DbgPrint(MID_TRACE,("No provider (err)\n"));
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
#if 0 /* XXX empty select is not an error */
|
||||||
} else {
|
} else {
|
||||||
WSASetLastError(WSAEINVAL);
|
WSASetLastError(WSAEINVAL);
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
Count = Provider->ProcTable.lpWSPSelect(
|
||||||
nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
|
nfds, readfds, writefds, exceptfds, (LPTIMEVAL)timeout, &Errno);
|
||||||
|
|
||||||
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
WS_DbgPrint(MAX_TRACE, ("[%x] Select: Count %d Errno %x\n",
|
||||||
|
Provider, Count, Errno));
|
||||||
|
|
||||||
DereferenceProviderByPointer(Provider);
|
DereferenceProviderByPointer(Provider);
|
||||||
|
|
||||||
|
@ -376,6 +393,7 @@ select(
|
||||||
WSASetLastError(Errno);
|
WSASetLastError(Errno);
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Count;
|
return Count;
|
||||||
}
|
}
|
||||||
|
@ -630,6 +648,20 @@ WSAIoctl(
|
||||||
return Status;
|
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
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
|
|
@ -636,23 +636,6 @@ WSACancelAsyncRequest(
|
||||||
return 0;
|
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 */
|
/* WinSock Service Provider support functions */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue