Author: cmihail Date: Sun Jul 3 12:03:49 2011 New Revision: 52516
URL: http://svn.reactos.org/svn/reactos?rev=52516&view=rev Log: [AFD] 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
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -355,7 +355,7 @@ NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); 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.Information = (NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0); @@ -369,6 +369,7 @@
if (NT_SUCCESS(Status)) { + DbgPrint("[AFD, StreamSocketConnectComplete] Making socket into connection\n"); Status = MakeSocketIntoConnection(FCB);
if (!NT_SUCCESS(Status)) @@ -377,21 +378,21 @@ return Status; }
- FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength, + FCB->FilledConnectData = MIN(FCB->ConnectReturnInfo->UserDataLength, FCB->ConnectDataSize); if (FCB->FilledConnectData) { RtlCopyMemory(FCB->ConnectData, - FCB->ConnectInfo->UserData, + FCB->ConnectReturnInfo->UserData, FCB->FilledConnectData); }
- FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength, + FCB->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength, FCB->ConnectOptionsSize); if (FCB->FilledConnectOptions) { RtlCopyMemory(FCB->ConnectOptions, - FCB->ConnectInfo->Options, + FCB->ConnectReturnInfo->Options, FCB->FilledConnectOptions); }
@@ -415,6 +416,7 @@ SocketStateUnlock(FCB);
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); + DbgPrint("[AFD, StreamSocketConnectComplete] Leaving. Status = 0x%x\n", Status);
return Status; } @@ -430,7 +432,6 @@ PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext; PAFD_CONNECT_INFO ConnectReq; - PTDI_CONNECTION_INFORMATION TargetAddress; AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if (!SocketAcquireStateLock(FCB)) @@ -507,41 +508,42 @@ if (!NT_SUCCESS(Status)) 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 (FCB->ConnectCallInfo) ExFreePool(FCB->ConnectCallInfo); + Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, + &ConnectReq->RemoteAddress); + } + else + break;
if (NT_SUCCESS(Status)) { - TargetAddress->UserData = FCB->ConnectData; - TargetAddress->UserDataLength = FCB->ConnectDataSize; - TargetAddress->Options = FCB->ConnectOptions; - TargetAddress->OptionsLength = FCB->ConnectOptionsSize; - - AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); - 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;
AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); - Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT ); + Status = QueueUserModeIrp(FCB, Irp, FUNCTION_CONNECT); if (Status == STATUS_PENDING) { - Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest, + Status = TdiConnect(&FCB->ConnectIrp.InFlightRequest, FCB->Connection.Object, - TargetAddress, - FCB->ConnectInfo, + FCB->ConnectCallInfo, + FCB->ConnectReturnInfo, &FCB->ConnectIrp.Iosb, StreamSocketConnectComplete, - FCB ); + FCB); }
if (Status != STATUS_PENDING) FCB->State = SOCKET_STATE_BOUND; - - ExFreePool(TargetAddress);
SocketStateUnlock(FCB);
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -43,7 +43,10 @@ Status = MakeSocketIntoConnection( FCB );
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 ); }
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -373,6 +373,7 @@ }
FileObject->FsContext = FCB; + DbgPrint("FileObject->FsContext = 0x%x\n", FCB);
/* It seems that UDP sockets are writable from inception */ if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS) @@ -381,8 +382,8 @@
/* A datagram socket is always sendable */ FCB->PollState |= AFD_EVENT_SEND; - FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); }
if (!NT_SUCCESS(Status)) @@ -523,8 +524,11 @@ if ( FCB->AddressFrom ) ExFreePool(FCB->AddressFrom);
- if (FCB->ConnectInfo) - ExFreePool(FCB->ConnectInfo); + if (FCB->ConnectCallInfo) + ExFreePool(FCB->ConnectCallInfo); + + if (FCB->ConnectReturnInfo) + ExFreePool(FCB->ConnectReturnInfo);
if (FCB->ConnectData) ExFreePool(FCB->ConnectData); @@ -596,78 +600,101 @@
static NTSTATUS -DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp) +NTAPI +DisconnectComplete(PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context) +{ + PAFD_FCB FCB = Context; + PIRP CurrentIrp; + PLIST_ENTRY CurrentEntry; + + if( !SocketAcquireStateLock( FCB ) ) + return STATUS_FILE_CLOSED; + + ASSERT(FCB->DisconnectIrp.InFlightRequest == Irp); + FCB->DisconnectIrp.InFlightRequest = NULL; + + ASSERT(FCB->DisconnectPending); + //ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)); + + if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)) + { + FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, FCB->ConnectReturnInfo->UserDataLength); + if (FCB->FilledDisconnectData) + { + RtlCopyMemory(FCB->DisconnectData, + FCB->ConnectReturnInfo->UserData, + FCB->FilledDisconnectData); + } + + FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, FCB->ConnectReturnInfo->OptionsLength); + if (FCB->FilledDisconnectOptions) + { + RtlCopyMemory(FCB->DisconnectOptions, + FCB->ConnectReturnInfo->Options, + FCB->FilledDisconnectOptions); + } + } + + FCB->DisconnectPending = FALSE; + + 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; + else + FCB->PollState |= AFD_EVENT_ABORT; + FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status; + PollReeval(FCB->DeviceExt, FCB->FileObject); + + SocketStateUnlock(FCB); + + return Irp->IoStatus.Status; +} + +static +NTSTATUS +DoDisconnect(PAFD_FCB FCB) { PAFD_DISCONNECT_INFO DisReq; IO_STATUS_BLOCK Iosb; - PTDI_CONNECTION_INFORMATION ConnectionReturnInfo; - PIO_STACK_LOCATION CurrentIrpSp; - USHORT Flags = 0; NTSTATUS Status;
- CurrentIrpSp = IoGetCurrentIrpStackLocation(CurrentIrp); - DisReq = GetLockedData(CurrentIrp, CurrentIrpSp); - - if (DisReq->DisconnectType & AFD_DISCONNECT_SEND) - Flags |= TDI_DISCONNECT_RELEASE; - if (DisReq->DisconnectType & AFD_DISCONNECT_RECV || - DisReq->DisconnectType & AFD_DISCONNECT_ABORT) - Flags |= TDI_DISCONNECT_ABORT; - - Status = TdiBuildNullConnectionInfo(&ConnectionReturnInfo, - FCB->RemoteAddress->Address[0].AddressType); - if (NT_SUCCESS(Status)) - { - FCB->ConnectInfo->UserData = FCB->DisconnectData; - 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) - { - RtlCopyMemory(FCB->DisconnectData, - ConnectionReturnInfo->UserData, - FCB->FilledDisconnectData); - } - - FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength); - if (FCB->FilledDisconnectOptions) - { - RtlCopyMemory(FCB->DisconnectOptions, - ConnectionReturnInfo->Options, - FCB->FilledDisconnectOptions); - } - } - - ExFreePool(ConnectionReturnInfo); - - if (Flags & TDI_DISCONNECT_RELEASE) - FCB->PollState |= AFD_EVENT_DISCONNECT; - else - FCB->PollState |= AFD_EVENT_ABORT; - - FCB->PollStatus[FD_CLOSE_BIT] = Status; - PollReeval(FCB->DeviceExt, FCB->FileObject); - } - - CurrentIrp->IoStatus.Status = Status; - CurrentIrp->IoStatus.Information = 0; - UnlockRequest(CurrentIrp, CurrentIrpSp); - (void)IoSetCancelRoutine(CurrentIrp, NULL); - - 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; } @@ -675,20 +702,12 @@ VOID RetryDisconnectCompletion(PAFD_FCB FCB) { - if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND])) - { - PIRP CurrentIrp; - PLIST_ENTRY CurrentEntry; - - ASSERT(FCB->RemoteAddress); - - while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) - { - CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); - CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); - - DoDisconnect(FCB, CurrentIrp); - } + ASSERT(FCB->RemoteAddress); + + if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && FCB->DisconnectPending) + { + /* Sends are done; fire off a TDI_DISCONNECT request */ + DoDisconnect(FCB); } }
@@ -702,6 +721,8 @@ PAFD_DISCONNECT_INFO DisReq; NTSTATUS Status = STATUS_SUCCESS; USHORT Flags = 0; + PLIST_ENTRY CurrentEntry; + PIRP CurrentIrp;
if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); @@ -717,23 +738,52 @@
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) { - if (!FCB->ConnectInfo) + if (!FCB->ConnectCallInfo) return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
- if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (Flags & TDI_DISCONNECT_ABORT)) - { - /* Go ahead an execute the disconnect because we're ready for it */ - Status = DoDisconnect(FCB, Irp); + if (FCB->DisconnectPending) + { + if (FCB->DisconnectIrp.InFlightRequest) + { + IoCancelIrp(FCB->DisconnectIrp.InFlightRequest); + ASSERT(!FCB->DisconnectIrp.InFlightRequest); + } + else + { + while (!IsListEmpty(&FCB->PendingIrpList[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); + }
- /* DoDisconnect takes care of the IRP */ + if (Status != STATUS_PENDING) + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + } + + if (Status == STATUS_PENDING) + { SocketStateUnlock(FCB); - + return Status; - } - else - { - /* We have a graceful disconnect waiting on pending sends to complete */ - return LeaveIrpUntilLater(FCB, Irp, FUNCTION_DISCONNECT); }
} @@ -983,6 +1033,8 @@ PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; KIRQL OldIrql; PAFD_ACTIVE_POLL Poll; + + DbgPrint("[AFD, AfdCancelHandler] called\n");
IoReleaseCancelSpinLock(Irp->CancelIrql);
@@ -1032,37 +1084,43 @@ case IOCTL_AFD_SELECT: KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql);
- CurrentEntry = DeviceExt->Polls.Flink; - while (CurrentEntry != &DeviceExt->Polls) - { - Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry); - - if (Irp == Poll->Irp) + CurrentEntry = DeviceExt->Polls.Flink; + while (CurrentEntry != &DeviceExt->Polls) { - CleanupPendingIrp(FCB, Irp, IrpSp, Poll); - KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); - SocketStateUnlock(FCB); - return; + Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry); + + if (Irp == Poll->Irp) + { + CleanupPendingIrp(FCB, Irp, IrpSp, Poll); + KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); + SocketStateUnlock(FCB); + + DbgPrint("[AFD, AfdCancelHandler] Cancelled IRP\n"); + + return; + } + else + { + CurrentEntry = CurrentEntry->Flink; + } } - else - { - CurrentEntry = CurrentEntry->Flink; - } - } - - KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); - - SocketStateUnlock(FCB); + + KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); + + SocketStateUnlock(FCB);
- DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n"); - return; + DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n"); + return;
default: - ASSERT(FALSE); - UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); - return; - } - + ASSERT(FALSE); + UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); + return; + } + + DbgPrint("[AFD, AfdCancelHandler] Cancelling MSAFD -> AFD IRPs\n"); + + /* Cancel IRPs from MSAFD to AFD (pending IRPs) */ CurrentEntry = FCB->PendingIrpList[Function].Flink; while (CurrentEntry != &FCB->PendingIrpList[Function]) {
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -141,6 +141,7 @@ UINT i;
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 );
@@ -152,6 +153,8 @@ Irp = Poll->Irp; PollReq = Irp->AssociatedIrp.SystemBuffer; HandleArray = AFD_HANDLES(PollReq); + + DbgPrint("[AFD, KillSelectsForFCB] killing select 0x%x\n", Poll);
for (i = 0; i < PollReq->HandleCount; i++) { @@ -161,6 +164,7 @@ if ((PVOID)HandleArray[i].Handle == FileObject && (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) { + DbgPrint("[AFD, KillSelectsForFCB] Zeroing events and signaling socket\n"); ZeroEvents( PollReq->Handles, PollReq->HandleCount ); SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED ); } @@ -170,6 +174,7 @@ KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
AFD_DbgPrint(MID_TRACE,("Done\n")); + DbgPrint("[AFD, KillSelectsForFCB] Leaving\n"); }
NTSTATUS @@ -191,6 +196,10 @@ PollReq->HandleCount, (INT)(PollReq->Timeout.QuadPart)));
+ DbgPrint("[AFD, AfdSelect] Called. HandleCount = %d, Timeout = %d\n", + PollReq->HandleCount, + (INT)(PollReq->Timeout.QuadPart)); + SET_AFD_HANDLES(PollReq, LockHandles( PollReq->Handles, PollReq->HandleCount ));
@@ -266,6 +275,8 @@
KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
+ DbgPrint("[AFD, AfdSelect] Marking IRP with STATUS_PENDING\n"); + Status = STATUS_PENDING; IoMarkIrpPending( Irp ); (void)IoSetCancelRoutine(Irp, AfdCancelHandler); @@ -280,6 +291,7 @@ KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); + DbgPrint("[AFD, AfdSelect] Leaving. Status = 0x%x\n", Status);
return Status; }
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -1241,6 +1241,7 @@ }
NTSTATUS TdiDisconnect( + PIRP *Irp, PFILE_OBJECT TransportObject, PLARGE_INTEGER Time, USHORT Flags, @@ -1250,10 +1251,6 @@ PTDI_CONNECTION_INFORMATION RequestConnectionInfo, PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) { PDEVICE_OBJECT DeviceObject; - KEVENT Event; - PIRP Irp; - - KeInitializeEvent(&Event, NotificationEvent, FALSE);
if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); @@ -1268,20 +1265,20 @@ return STATUS_INVALID_PARAMETER; }
- Irp = TdiBuildInternalDeviceControlIrp + *Irp = TdiBuildInternalDeviceControlIrp ( TDI_DISCONNECT, /* Sub function */ DeviceObject, /* Device object */ TransportObject, /* File object */ - &Event, /* Event */ + NULL, /* Event */ Iosb ); /* Status */
- if (!Irp) { + if (!*Irp) { AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; }
TdiBuildDisconnect - (Irp, /* I/O Request Packet */ + (*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ CompletionRoutine, /* Completion routine */ @@ -1291,7 +1288,9 @@ RequestConnectionInfo, /* Indication of who to disconnect */ ReturnConnectionInfo); /* Indication of who disconnected */
- return TdiCall(Irp, DeviceObject, &Event, Iosb); + TdiCall(*Irp, DeviceObject, NULL, Iosb); + + return STATUS_PENDING; }
/* EOF */
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -168,11 +168,20 @@ 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 */ if (FCB->Send.BytesUsed) { - FCB->PollState &= ~AFD_EVENT_SEND; - Status = TdiSend( &FCB->SendIrp.InFlightRequest, FCB->Connection.Object, 0, @@ -183,12 +192,6 @@ FCB );
RetryDisconnectCompletion(FCB); - } - else - { - FCB->PollState |= AFD_EVENT_SEND; - FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; - PollReeval( FCB->DeviceExt, FCB->FileObject ); }
SocketStateUnlock( FCB ); @@ -408,6 +411,7 @@ } else { + FCB->PollState &= ~AFD_EVENT_SEND; if (SendReq->AfdFlags & AFD_IMMEDIATE) { AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); @@ -438,6 +442,17 @@
AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n", 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);
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -182,10 +182,12 @@ PAFD_DEVICE_EXTENSION DeviceExt; BOOLEAN DelayedAccept; UINT ConnSeq; + USHORT DisconnectFlags; + BOOLEAN DisconnectPending; PTRANSPORT_ADDRESS LocalAddress, RemoteAddress; - PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo; + PTDI_CONNECTION_INFORMATION AddressFrom, ConnectCallInfo, ConnectReturnInfo; 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; KMUTEX Mutex; PKEVENT EventSelect;
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h [iso-8859-1] Sun Jul 3 12:03:49 2011 @@ -16,7 +16,8 @@ PFILE_OBJECT FileObject);
NTSTATUS TdiDisconnect -( PFILE_OBJECT TransportObject, +( PIRP *Irp, + PFILE_OBJECT TransportObject, PLARGE_INTEGER Time, USHORT Flags, PIO_STATUS_BLOCK Iosb,