mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:32:57 +00:00
[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 svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52516
This commit is contained in:
parent
9aa2d2c133
commit
75014f14eb
8 changed files with 252 additions and 160 deletions
|
@ -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;
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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])
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue