Kill only selects involving a named file descriptor when clearing exclusive

selects.  This makes ASECHO32 work perfectly.

svn path=/trunk/; revision=13430
This commit is contained in:
Art Yerkes 2005-02-06 07:56:45 +00:00
parent 8f344fcd2f
commit a6b98eefa1
3 changed files with 43 additions and 33 deletions

View file

@ -225,7 +225,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->PollState |= AFD_EVENT_CLOSE;
PollReeval( FCB->DeviceExt, FileObject );
KillSelectsForFCB( FCB->DeviceExt, FileObject );
KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect );

View file

@ -12,6 +12,25 @@
#include "tdiconn.h"
#include "debug.h"
VOID PrintEvents( ULONG Events ) {
char *events_list[] = { "AFD_EVENT_RECEIVE",
"AFD_EVENT_OOB_RECEIVE",
"AFD_EVENT_SEND",
"AFD_EVENT_DISCONNECT",
"AFD_EVENT_ABORT",
"AFD_EVENT_CLOSE",
"AFD_EVENT_CONNECT",
"AFD_EVENT_ACCEPT",
"AFD_EVENT_CONNECT_FAIL",
"AFD_EVENT_QOS",
"AFD_EVENT_GROUP_QOS",
NULL };
int i;
for( i = 0; events_list[i]; i++ )
if( Events & (1 << i) ) DbgPrint("%s ", events_list[i] );
}
VOID CopyBackStatus( PAFD_HANDLE HandleArray,
UINT HandleCount ) {
UINT i;
@ -94,7 +113,8 @@ VOID SelectTimeout( PKDPC Dpc,
}
VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject ) {
PFILE_OBJECT FileObject,
BOOLEAN OnlyExclusive ) {
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
PAFD_ACTIVE_POLL Poll;
@ -116,42 +136,19 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
for( i = 0; i < PollReq->HandleCount; i++ ) {
AFD_DbgPrint(MAX_TRACE,("Req: %x, This %x\n",
PollReq->Handles[i].Handle, FileObject));
if( (PVOID)PollReq->Handles[i].Handle == FileObject ) {
if( (PVOID)PollReq->Handles[i].Handle == FileObject &&
(!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) {
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
SignalSocket( Poll, PollReq, STATUS_SUCCESS );
}
}
}
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
AFD_DbgPrint(MID_TRACE,("Done\n"));
}
VOID KillExclusiveSelects( PAFD_DEVICE_EXTENSION DeviceExt ) {
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
PAFD_ACTIVE_POLL Poll;
PIRP Irp;
PAFD_POLL_INFO PollReq;
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
ListEntry = DeviceExt->Polls.Flink;
while ( ListEntry != &DeviceExt->Polls ) {
Poll = CONTAINING_RECORD(ListEntry, AFD_ACTIVE_POLL, ListEntry);
ListEntry = ListEntry->Flink;
if( Poll->Exclusive ) {
Irp = Poll->Irp;
PollReq = Irp->AssociatedIrp.SystemBuffer;
ZeroEvents( PollReq->Handles, PollReq->HandleCount );
SignalSocket( Poll, PollReq, STATUS_CANCELLED );
}
}
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
}
NTSTATUS STDCALL
AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp ) {
@ -175,9 +172,6 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
SET_AFD_HANDLES(PollReq,
LockHandles( PollReq->Handles, PollReq->HandleCount ));
if( Exclusive ) KillExclusiveSelects( DeviceExt );
if( !AFD_HANDLES(PollReq) ) {
Irp->IoStatus.Status = STATUS_NO_MEMORY;
Irp->IoStatus.Information = 0;
@ -185,6 +179,16 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
return Irp->IoStatus.Status;
}
if( Exclusive ) {
for( i = 0; i < PollReq->HandleCount; i++ ) {
if( !AFD_HANDLES(PollReq)[i].Handle ) continue;
KillSelectsForFCB( DeviceExt,
(PFILE_OBJECT)AFD_HANDLES(PollReq)[i].Handle,
TRUE );
}
}
ZeroEvents( PollReq->Handles,
PollReq->HandleCount );
@ -218,6 +222,12 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PollReq->Handles[i].Status = AFD_EVENT_CLOSE;
Signalled++;
} else {
#ifdef DBG
DbgPrint("AFD: Select Events: ");
PrintEvents( PollReq->Handles[i].Events );
DbgPrint("\n");
#endif
PollReq->Handles[i].Status =
PollReq->Handles[i].Events & FCB->PollState;
if( PollReq->Handles[i].Status ) {

View file

@ -263,7 +263,7 @@ AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp );
VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceObject, PFILE_OBJECT FileObject );
VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject );
PFILE_OBJECT FileObject, BOOLEAN ExclusiveOnly );
/* tdi.c */