merge r52497
- Rewrite disconnect to work asynchronously

merge r52492
- Fix several bugs related to the FD_WRITE event
- We would not set the sendable poll state if the socket had data waiting to be sent even if there was buffer space
- We did not set the poll state after performing a send
- We did not clear the sendable poll state if we ran out of buffer space

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52516
This commit is contained in:
Claudiu Mihail 2011-07-03 12:03:49 +00:00
parent 9aa2d2c133
commit 75014f14eb
8 changed files with 252 additions and 160 deletions

View file

@ -355,7 +355,7 @@ StreamSocketConnectComplete
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp)); AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp));
DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x\n", NextIrp); DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x with Status = 0x%x\n", NextIrp, Status);
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);
@ -369,6 +369,7 @@ StreamSocketConnectComplete
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DbgPrint("[AFD, StreamSocketConnectComplete] Making socket into connection\n");
Status = MakeSocketIntoConnection(FCB); Status = MakeSocketIntoConnection(FCB);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -377,21 +378,21 @@ StreamSocketConnectComplete
return Status; return Status;
} }
FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength, FCB->FilledConnectData = MIN(FCB->ConnectReturnInfo->UserDataLength,
FCB->ConnectDataSize); FCB->ConnectDataSize);
if (FCB->FilledConnectData) if (FCB->FilledConnectData)
{ {
RtlCopyMemory(FCB->ConnectData, RtlCopyMemory(FCB->ConnectData,
FCB->ConnectInfo->UserData, FCB->ConnectReturnInfo->UserData,
FCB->FilledConnectData); FCB->FilledConnectData);
} }
FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength, FCB->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength,
FCB->ConnectOptionsSize); FCB->ConnectOptionsSize);
if (FCB->FilledConnectOptions) if (FCB->FilledConnectOptions)
{ {
RtlCopyMemory(FCB->ConnectOptions, RtlCopyMemory(FCB->ConnectOptions,
FCB->ConnectInfo->Options, FCB->ConnectReturnInfo->Options,
FCB->FilledConnectOptions); FCB->FilledConnectOptions);
} }
@ -415,6 +416,7 @@ StreamSocketConnectComplete
SocketStateUnlock(FCB); SocketStateUnlock(FCB);
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
DbgPrint("[AFD, StreamSocketConnectComplete] Leaving. Status = 0x%x\n", Status);
return Status; return Status;
} }
@ -430,7 +432,6 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext; PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
PAFD_CONNECT_INFO ConnectReq; PAFD_CONNECT_INFO ConnectReq;
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)) if (!SocketAcquireStateLock(FCB))
@ -507,21 +508,24 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
break; break;
Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, &ConnectReq->RemoteAddress); if (FCB->ConnectReturnInfo) ExFreePool(FCB->ConnectReturnInfo);
Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, &ConnectReq->RemoteAddress);
if (NT_SUCCESS(Status))
Status = TdiBuildConnectionInfo(&TargetAddress, &ConnectReq->RemoteAddress);
else break;
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
TargetAddress->UserData = FCB->ConnectData; if (FCB->ConnectCallInfo) ExFreePool(FCB->ConnectCallInfo);
TargetAddress->UserDataLength = FCB->ConnectDataSize; Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo,
TargetAddress->Options = FCB->ConnectOptions; &ConnectReq->RemoteAddress);
TargetAddress->OptionsLength = FCB->ConnectOptionsSize; }
else
break;
AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); if (NT_SUCCESS(Status))
DbgPrint("[AFD, AfdStreamSocketConnect] Queueing IRP %x\n", Irp); {
FCB->ConnectCallInfo->UserData = FCB->ConnectData;
FCB->ConnectCallInfo->UserDataLength = FCB->ConnectDataSize;
FCB->ConnectCallInfo->Options = FCB->ConnectOptions;
FCB->ConnectCallInfo->OptionsLength = FCB->ConnectOptionsSize;
FCB->State = SOCKET_STATE_CONNECTING; FCB->State = SOCKET_STATE_CONNECTING;
@ -531,8 +535,8 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
{ {
Status = TdiConnect(&FCB->ConnectIrp.InFlightRequest, Status = TdiConnect(&FCB->ConnectIrp.InFlightRequest,
FCB->Connection.Object, FCB->Connection.Object,
TargetAddress, FCB->ConnectCallInfo,
FCB->ConnectInfo, FCB->ConnectReturnInfo,
&FCB->ConnectIrp.Iosb, &FCB->ConnectIrp.Iosb,
StreamSocketConnectComplete, StreamSocketConnectComplete,
FCB); FCB);
@ -541,8 +545,6 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
FCB->State = SOCKET_STATE_BOUND; FCB->State = SOCKET_STATE_BOUND;
ExFreePool(TargetAddress);
SocketStateUnlock(FCB); SocketStateUnlock(FCB);
return Status; return Status;

View file

@ -43,7 +43,10 @@ SatisfyAccept
Status = MakeSocketIntoConnection( FCB ); Status = MakeSocketIntoConnection( FCB );
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, FCB->RemoteAddress); Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, FCB->RemoteAddress);
if (NT_SUCCESS(Status))
Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, FCB->RemoteAddress);
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
} }

View file

@ -373,6 +373,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
} }
FileObject->FsContext = FCB; FileObject->FsContext = FCB;
DbgPrint("FileObject->FsContext = 0x%x\n", 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)
@ -523,8 +524,11 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if ( FCB->AddressFrom ) if ( FCB->AddressFrom )
ExFreePool(FCB->AddressFrom); ExFreePool(FCB->AddressFrom);
if (FCB->ConnectInfo) if (FCB->ConnectCallInfo)
ExFreePool(FCB->ConnectInfo); ExFreePool(FCB->ConnectCallInfo);
if (FCB->ConnectReturnInfo)
ExFreePool(FCB->ConnectReturnInfo);
if (FCB->ConnectData) if (FCB->ConnectData)
ExFreePool(FCB->ConnectData); ExFreePool(FCB->ConnectData);
@ -596,78 +600,101 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
static static
NTSTATUS NTSTATUS
DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp) NTAPI
DisconnectComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{ {
PAFD_DISCONNECT_INFO DisReq; PAFD_FCB FCB = Context;
IO_STATUS_BLOCK Iosb; PIRP CurrentIrp;
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo; PLIST_ENTRY CurrentEntry;
PIO_STACK_LOCATION CurrentIrpSp;
USHORT Flags = 0;
NTSTATUS Status;
CurrentIrpSp = IoGetCurrentIrpStackLocation(CurrentIrp); if( !SocketAcquireStateLock( FCB ) )
DisReq = GetLockedData(CurrentIrp, CurrentIrpSp); return STATUS_FILE_CLOSED;
if (DisReq->DisconnectType & AFD_DISCONNECT_SEND) ASSERT(FCB->DisconnectIrp.InFlightRequest == Irp);
Flags |= TDI_DISCONNECT_RELEASE; FCB->DisconnectIrp.InFlightRequest = NULL;
if (DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
DisReq->DisconnectType & AFD_DISCONNECT_ABORT)
Flags |= TDI_DISCONNECT_ABORT;
Status = TdiBuildNullConnectionInfo(&ConnectionReturnInfo, ASSERT(FCB->DisconnectPending);
FCB->RemoteAddress->Address[0].AddressType); //ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT));
if (NT_SUCCESS(Status))
if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE))
{ {
FCB->ConnectInfo->UserData = FCB->DisconnectData; FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, FCB->ConnectReturnInfo->UserDataLength);
FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
FCB->ConnectInfo->Options = FCB->DisconnectOptions;
FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize;
Status = TdiDisconnect(FCB->Connection.Object,
&DisReq->Timeout,
Flags,
&Iosb,
NULL,
NULL,
FCB->ConnectInfo,
ConnectionReturnInfo);
if (NT_SUCCESS(Status))
{
FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength);
if (FCB->FilledDisconnectData) if (FCB->FilledDisconnectData)
{ {
RtlCopyMemory(FCB->DisconnectData, RtlCopyMemory(FCB->DisconnectData,
ConnectionReturnInfo->UserData, FCB->ConnectReturnInfo->UserData,
FCB->FilledDisconnectData); FCB->FilledDisconnectData);
} }
FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength); FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, FCB->ConnectReturnInfo->OptionsLength);
if (FCB->FilledDisconnectOptions) if (FCB->FilledDisconnectOptions)
{ {
RtlCopyMemory(FCB->DisconnectOptions, RtlCopyMemory(FCB->DisconnectOptions,
ConnectionReturnInfo->Options, FCB->ConnectReturnInfo->Options,
FCB->FilledDisconnectOptions); FCB->FilledDisconnectOptions);
} }
} }
ExFreePool(ConnectionReturnInfo); FCB->DisconnectPending = FALSE;
if (Flags & TDI_DISCONNECT_RELEASE) while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
{
CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
CurrentIrp->IoStatus.Status = Irp->IoStatus.Status;
CurrentIrp->IoStatus.Information = 0;
UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp));
(void)IoSetCancelRoutine(CurrentIrp, NULL);
IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT );
}
if (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)
FCB->PollState |= AFD_EVENT_DISCONNECT; FCB->PollState |= AFD_EVENT_DISCONNECT;
else else
FCB->PollState |= AFD_EVENT_ABORT; FCB->PollState |= AFD_EVENT_ABORT;
FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status;
FCB->PollStatus[FD_CLOSE_BIT] = Status;
PollReeval(FCB->DeviceExt, FCB->FileObject); PollReeval(FCB->DeviceExt, FCB->FileObject);
SocketStateUnlock(FCB);
return Irp->IoStatus.Status;
} }
CurrentIrp->IoStatus.Status = Status; static
CurrentIrp->IoStatus.Information = 0; NTSTATUS
UnlockRequest(CurrentIrp, CurrentIrpSp); DoDisconnect(PAFD_FCB FCB)
(void)IoSetCancelRoutine(CurrentIrp, NULL); {
PAFD_DISCONNECT_INFO DisReq;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT); ASSERT(FCB->DisconnectPending);
if (FCB->DisconnectIrp.InFlightRequest)
{
return STATUS_PENDING;
}
FCB->ConnectCallInfo->UserData = FCB->DisconnectData;
FCB->ConnectCallInfo->UserDataLength = FCB->DisconnectDataSize;
FCB->ConnectCallInfo->Options = FCB->DisconnectOptions;
FCB->ConnectCallInfo->OptionsLength = FCB->DisconnectOptionsSize;
Status = TdiDisconnect(&FCB->DisconnectIrp.InFlightRequest,
FCB->Connection.Object,
&DisReq->Timeout,
FCB->DisconnectFlags,
&Iosb,
DisconnectComplete,
FCB,
FCB->ConnectCallInfo,
FCB->ConnectReturnInfo);
if (Status != STATUS_PENDING)
{
FCB->DisconnectPending = FALSE;
}
return Status; return Status;
} }
@ -675,20 +702,12 @@ DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp)
VOID VOID
RetryDisconnectCompletion(PAFD_FCB FCB) RetryDisconnectCompletion(PAFD_FCB FCB)
{ {
if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]))
{
PIRP CurrentIrp;
PLIST_ENTRY CurrentEntry;
ASSERT(FCB->RemoteAddress); ASSERT(FCB->RemoteAddress);
while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && FCB->DisconnectPending)
{ {
CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); /* Sends are done; fire off a TDI_DISCONNECT request */
CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); DoDisconnect(FCB);
DoDisconnect(FCB, CurrentIrp);
}
} }
} }
@ -702,6 +721,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
PAFD_DISCONNECT_INFO DisReq; PAFD_DISCONNECT_INFO DisReq;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
USHORT Flags = 0; USHORT Flags = 0;
PLIST_ENTRY CurrentEntry;
PIRP CurrentIrp;
if (!SocketAcquireStateLock(FCB)) if (!SocketAcquireStateLock(FCB))
return LostSocket(Irp); return LostSocket(Irp);
@ -717,23 +738,52 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
{ {
if (!FCB->ConnectInfo) if (!FCB->ConnectCallInfo)
return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (Flags & TDI_DISCONNECT_ABORT)) if (FCB->DisconnectPending)
{ {
/* Go ahead an execute the disconnect because we're ready for it */ if (FCB->DisconnectIrp.InFlightRequest)
Status = DoDisconnect(FCB, Irp); {
IoCancelIrp(FCB->DisconnectIrp.InFlightRequest);
/* DoDisconnect takes care of the IRP */ ASSERT(!FCB->DisconnectIrp.InFlightRequest);
SocketStateUnlock(FCB);
return Status;
} }
else else
{ {
/* We have a graceful disconnect waiting on pending sends to complete */ while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
return LeaveIrpUntilLater(FCB, Irp, FUNCTION_DISCONNECT); {
CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
CurrentIrp->IoStatus.Information = 0;
UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp));
(void)IoSetCancelRoutine(CurrentIrp, NULL);
IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT );
}
}
}
FCB->DisconnectFlags = Flags;
FCB->DisconnectPending = TRUE;
Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT);
if (Status == STATUS_PENDING)
{
if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT))
{
/* Go ahead an execute the disconnect because we're ready for it */
Status = DoDisconnect(FCB);
}
if (Status != STATUS_PENDING)
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
}
if (Status == STATUS_PENDING)
{
SocketStateUnlock(FCB);
return Status;
} }
} }
@ -984,6 +1034,8 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
KIRQL OldIrql; KIRQL OldIrql;
PAFD_ACTIVE_POLL Poll; PAFD_ACTIVE_POLL Poll;
DbgPrint("[AFD, AfdCancelHandler] called\n");
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
if (!SocketAcquireStateLock(FCB)) if (!SocketAcquireStateLock(FCB))
@ -1042,6 +1094,9 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
CleanupPendingIrp(FCB, Irp, IrpSp, Poll); CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
SocketStateUnlock(FCB); SocketStateUnlock(FCB);
DbgPrint("[AFD, AfdCancelHandler] Cancelled IRP\n");
return; return;
} }
else else
@ -1063,6 +1118,9 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
return; return;
} }
DbgPrint("[AFD, AfdCancelHandler] Cancelling MSAFD -> AFD IRPs\n");
/* Cancel IRPs from MSAFD to AFD (pending IRPs) */
CurrentEntry = FCB->PendingIrpList[Function].Flink; CurrentEntry = FCB->PendingIrpList[Function].Flink;
while (CurrentEntry != &FCB->PendingIrpList[Function]) while (CurrentEntry != &FCB->PendingIrpList[Function])
{ {

View file

@ -141,6 +141,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
UINT i; UINT i;
AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %x\n", FileObject)); AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %x\n", FileObject));
DbgPrint("[AFD, KillSelectsForFCB] Called for FileObject->FsContext = 0x%x\n", FileObject->FsContext);
KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
@ -153,6 +154,8 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
PollReq = Irp->AssociatedIrp.SystemBuffer; PollReq = Irp->AssociatedIrp.SystemBuffer;
HandleArray = AFD_HANDLES(PollReq); HandleArray = AFD_HANDLES(PollReq);
DbgPrint("[AFD, KillSelectsForFCB] killing select 0x%x\n", Poll);
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",
@ -161,6 +164,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
if ((PVOID)HandleArray[i].Handle == FileObject && if ((PVOID)HandleArray[i].Handle == FileObject &&
(!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) )
{ {
DbgPrint("[AFD, KillSelectsForFCB] Zeroing events and signaling socket\n");
ZeroEvents( PollReq->Handles, PollReq->HandleCount ); ZeroEvents( PollReq->Handles, PollReq->HandleCount );
SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED ); SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED );
} }
@ -170,6 +174,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
AFD_DbgPrint(MID_TRACE,("Done\n")); AFD_DbgPrint(MID_TRACE,("Done\n"));
DbgPrint("[AFD, KillSelectsForFCB] Leaving\n");
} }
NTSTATUS NTSTATUS
@ -191,6 +196,10 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
PollReq->HandleCount, PollReq->HandleCount,
(INT)(PollReq->Timeout.QuadPart))); (INT)(PollReq->Timeout.QuadPart)));
DbgPrint("[AFD, AfdSelect] Called. HandleCount = %d, Timeout = %d\n",
PollReq->HandleCount,
(INT)(PollReq->Timeout.QuadPart));
SET_AFD_HANDLES(PollReq, SET_AFD_HANDLES(PollReq,
LockHandles( PollReq->Handles, PollReq->HandleCount )); LockHandles( PollReq->Handles, PollReq->HandleCount ));
@ -266,6 +275,8 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc ); KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
DbgPrint("[AFD, AfdSelect] Marking IRP with STATUS_PENDING\n");
Status = STATUS_PENDING; Status = STATUS_PENDING;
IoMarkIrpPending( Irp ); IoMarkIrpPending( Irp );
(void)IoSetCancelRoutine(Irp, AfdCancelHandler); (void)IoSetCancelRoutine(Irp, AfdCancelHandler);
@ -280,6 +291,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
DbgPrint("[AFD, AfdSelect] Leaving. Status = 0x%x\n", Status);
return Status; return Status;
} }

View file

@ -1241,6 +1241,7 @@ NTSTATUS TdiSendDatagram(
} }
NTSTATUS TdiDisconnect( NTSTATUS TdiDisconnect(
PIRP *Irp,
PFILE_OBJECT TransportObject, PFILE_OBJECT TransportObject,
PLARGE_INTEGER Time, PLARGE_INTEGER Time,
USHORT Flags, USHORT Flags,
@ -1250,10 +1251,6 @@ NTSTATUS TdiDisconnect(
PTDI_CONNECTION_INFORMATION RequestConnectionInfo, PTDI_CONNECTION_INFORMATION RequestConnectionInfo,
PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) { PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) {
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
KEVENT Event;
PIRP Irp;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
if (!TransportObject) { if (!TransportObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
@ -1268,20 +1265,20 @@ NTSTATUS TdiDisconnect(
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
Irp = TdiBuildInternalDeviceControlIrp *Irp = TdiBuildInternalDeviceControlIrp
( TDI_DISCONNECT, /* Sub function */ ( TDI_DISCONNECT, /* Sub function */
DeviceObject, /* Device object */ DeviceObject, /* Device object */
TransportObject, /* File object */ TransportObject, /* File object */
&Event, /* Event */ NULL, /* Event */
Iosb ); /* Status */ Iosb ); /* Status */
if (!Irp) { if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
TdiBuildDisconnect TdiBuildDisconnect
(Irp, /* I/O Request Packet */ (*Irp, /* I/O Request Packet */
DeviceObject, /* Device object */ DeviceObject, /* Device object */
TransportObject, /* File object */ TransportObject, /* File object */
CompletionRoutine, /* Completion routine */ CompletionRoutine, /* Completion routine */
@ -1291,7 +1288,9 @@ NTSTATUS TdiDisconnect(
RequestConnectionInfo, /* Indication of who to disconnect */ RequestConnectionInfo, /* Indication of who to disconnect */
ReturnConnectionInfo); /* Indication of who disconnected */ ReturnConnectionInfo); /* Indication of who disconnected */
return TdiCall(Irp, DeviceObject, &Event, Iosb); TdiCall(*Irp, DeviceObject, NULL, Iosb);
return STATUS_PENDING;
} }
/* EOF */ /* EOF */

View file

@ -168,11 +168,20 @@ SendComplete
break; break;
} }
if (FCB->Send.Size - FCB->Send.BytesUsed != 0)
{
FCB->PollState |= AFD_EVENT_SEND;
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
else
{
FCB->PollState &= ~AFD_EVENT_SEND;
}
/* Some data is still waiting */ /* Some data is still waiting */
if (FCB->Send.BytesUsed) if (FCB->Send.BytesUsed)
{ {
FCB->PollState &= ~AFD_EVENT_SEND;
Status = TdiSend( &FCB->SendIrp.InFlightRequest, Status = TdiSend( &FCB->SendIrp.InFlightRequest,
FCB->Connection.Object, FCB->Connection.Object,
0, 0,
@ -184,12 +193,6 @@ SendComplete
RetryDisconnectCompletion(FCB); RetryDisconnectCompletion(FCB);
} }
else
{
FCB->PollState |= AFD_EVENT_SEND;
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
@ -408,6 +411,7 @@ AfdConnectedSocketWriteData
} }
else else
{ {
FCB->PollState &= ~AFD_EVENT_SEND;
if (SendReq->AfdFlags & AFD_IMMEDIATE) if (SendReq->AfdFlags & AFD_IMMEDIATE)
{ {
AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
@ -440,6 +444,17 @@ AfdConnectedSocketWriteData
Status, TotalBytesCopied)); Status, TotalBytesCopied));
} }
if (SpaceAvail)
{
FCB->PollState |= AFD_EVENT_SEND;
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
else
{
FCB->PollState &= ~AFD_EVENT_SEND;
}
RetryDisconnectCompletion(FCB); RetryDisconnectCompletion(FCB);
return UnlockAndMaybeComplete(FCB, Status, Irp, TotalBytesCopied); return UnlockAndMaybeComplete(FCB, Status, Irp, TotalBytesCopied);

View file

@ -182,10 +182,12 @@ typedef struct _AFD_FCB {
PAFD_DEVICE_EXTENSION DeviceExt; PAFD_DEVICE_EXTENSION DeviceExt;
BOOLEAN DelayedAccept; BOOLEAN DelayedAccept;
UINT ConnSeq; UINT ConnSeq;
USHORT DisconnectFlags;
BOOLEAN DisconnectPending;
PTRANSPORT_ADDRESS LocalAddress, RemoteAddress; PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo; PTDI_CONNECTION_INFORMATION AddressFrom, ConnectCallInfo, ConnectReturnInfo;
AFD_TDI_OBJECT AddressFile, Connection; AFD_TDI_OBJECT AddressFile, Connection;
AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp; AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp, DisconnectIrp;
AFD_DATA_WINDOW Send, Recv; AFD_DATA_WINDOW Send, Recv;
KMUTEX Mutex; KMUTEX Mutex;
PKEVENT EventSelect; PKEVENT EventSelect;

View file

@ -16,7 +16,8 @@ NTSTATUS TdiCloseDevice(HANDLE Handle,
PFILE_OBJECT FileObject); PFILE_OBJECT FileObject);
NTSTATUS TdiDisconnect NTSTATUS TdiDisconnect
( PFILE_OBJECT TransportObject, ( PIRP *Irp,
PFILE_OBJECT TransportObject,
PLARGE_INTEGER Time, PLARGE_INTEGER Time,
USHORT Flags, USHORT Flags,
PIO_STATUS_BLOCK Iosb, PIO_STATUS_BLOCK Iosb,