mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 01:43:02 +00:00
[AFD, TCPIP]
Bind issue seems solved now. Server app can be restarted without failing at binding. More information is at r52166. Patch by cgutman. svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52170
This commit is contained in:
parent
c31d8d66b9
commit
2cc1ca91c8
8 changed files with 203 additions and 93 deletions
|
@ -65,6 +65,7 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PAFD_BIND_DATA BindReq;
|
PAFD_BIND_DATA BindReq;
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
AFD_DbgPrint(MID_TRACE,("Called\n"));
|
||||||
|
DbgPrint("[AFD, AfdBindSocket] Called\n");
|
||||||
|
|
||||||
if ( !SocketAcquireStateLock( FCB ) )
|
if ( !SocketAcquireStateLock( FCB ) )
|
||||||
return LostSocket( Irp );
|
return LostSocket( Irp );
|
||||||
|
@ -109,6 +110,8 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
FCB->State = SOCKET_STATE_BOUND;
|
FCB->State = SOCKET_STATE_BOUND;
|
||||||
|
|
||||||
|
DbgPrint("[AFD, AfdBindSocket] Leaving\n");
|
||||||
|
|
||||||
/* MSAFD relies on us returning the address file handle in the IOSB */
|
/* MSAFD relies on us returning the address file handle in the IOSB */
|
||||||
return UnlockAndMaybeComplete( FCB, Status, Irp, (ULONG_PTR)FCB->AddressFile.Handle );
|
return UnlockAndMaybeComplete( FCB, Status, Irp, (ULONG_PTR)FCB->AddressFile.Handle );
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,22 +114,22 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAFD_FCB FCB = (PAFD_FCB)Context;
|
PAFD_FCB FCB = (PAFD_FCB)Context;
|
||||||
PAFD_TDI_OBJECT_QELT Qelt;
|
PAFD_TDI_OBJECT_QELT Qelt;
|
||||||
PLIST_ENTRY NextIrpEntry, QeltEntry;
|
PLIST_ENTRY NextIrpEntry;
|
||||||
PIRP NextIrp;
|
PIRP NextIrp;
|
||||||
|
|
||||||
DbgPrint("[AFD, ListenComplete] Called\n");
|
DbgPrint("[AFD, ListenComplete] Called\n");
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if ( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
FCB->ListenIrp.InFlightRequest = NULL;
|
FCB->ListenIrp.InFlightRequest = NULL;
|
||||||
|
|
||||||
DbgPrint("[AFD, ListenComplete] FCB->State = 0x%x (should be 0x%x)\n", FCB->State, SOCKET_STATE_CLOSED);
|
DbgPrint("[AFD, ListenComplete] FCB->State = 0x%x (should be 0x%x)\n", FCB->State, SOCKET_STATE_CLOSED);
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED )
|
if ( FCB->State == SOCKET_STATE_CLOSED )
|
||||||
{
|
{
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) )
|
while ( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) )
|
||||||
{
|
{
|
||||||
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_PREACCEPT]);
|
NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_PREACCEPT]);
|
||||||
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
@ -140,13 +140,6 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free all pending connections */
|
|
||||||
while( !IsListEmpty( &FCB->PendingConnections ) ) {
|
|
||||||
QeltEntry = RemoveHeadList(&FCB->PendingConnections);
|
|
||||||
Qelt = CONTAINING_RECORD(QeltEntry, AFD_TDI_OBJECT_QELT, ListEntry);
|
|
||||||
ExFreePool(Qelt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free ConnectionReturnInfo and ConnectionCallInfo */
|
/* Free ConnectionReturnInfo and ConnectionCallInfo */
|
||||||
if (FCB->ListenIrp.ConnectionReturnInfo)
|
if (FCB->ListenIrp.ConnectionReturnInfo)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +158,13 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
|
AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
|
||||||
AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", FCB->ListenIrp.Iosb.Status));
|
AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", Irp->IoStatus.Status));
|
||||||
|
|
||||||
|
if (Irp->IoStatus.Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
SocketStateUnlock(FCB);
|
||||||
|
return Irp->IoStatus.Status;
|
||||||
|
}
|
||||||
|
|
||||||
DbgPrint("[AFD, ListenComplete] Completing listen request.\n");
|
DbgPrint("[AFD, ListenComplete] Completing listen request.\n");
|
||||||
DbgPrint("[AFD, ListenComplete] IoStatus was %x\n", FCB->ListenIrp.Iosb.Status);
|
DbgPrint("[AFD, ListenComplete] IoStatus was %x\n", FCB->ListenIrp.Iosb.Status);
|
||||||
|
@ -202,7 +201,7 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Satisfy a pre-accept request if one is available */
|
/* Satisfy a pre-accept request if one is available */
|
||||||
if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
|
if ( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
|
||||||
!IsListEmpty( &FCB->PendingConnections ) )
|
!IsListEmpty( &FCB->PendingConnections ) )
|
||||||
{
|
{
|
||||||
PLIST_ENTRY PendingIrp =
|
PLIST_ENTRY PendingIrp =
|
||||||
|
@ -240,7 +239,7 @@ static NTSTATUS NTAPI ListenComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger a select return if appropriate */
|
/* Trigger a select return if appropriate */
|
||||||
if( !IsListEmpty( &FCB->PendingConnections ) )
|
if ( !IsListEmpty( &FCB->PendingConnections ) )
|
||||||
{
|
{
|
||||||
FCB->PollState |= AFD_EVENT_ACCEPT;
|
FCB->PollState |= AFD_EVENT_ACCEPT;
|
||||||
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
|
||||||
|
|
|
@ -252,10 +252,38 @@ NTSTATUS LostSocket( PIRP Irp ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
|
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Add the IRP to the queue in all cases (so AfdCancelHandler will work properly) */
|
||||||
InsertTailList( &FCB->PendingIrpList[Function],
|
InsertTailList( &FCB->PendingIrpList[Function],
|
||||||
&Irp->Tail.Overlay.ListEntry );
|
&Irp->Tail.Overlay.ListEntry );
|
||||||
IoMarkIrpPending(Irp);
|
|
||||||
(void)IoSetCancelRoutine(Irp, AfdCancelHandler);
|
/* Acquire the cancel spin lock and check the cancel bit */
|
||||||
|
IoAcquireCancelSpinLock(&Irp->CancelIrql);
|
||||||
|
if (!Irp->Cancel)
|
||||||
|
{
|
||||||
|
/* We are not cancelled; we're good to go so
|
||||||
|
* set the cancel routine, release the cancel spin lock,
|
||||||
|
* mark the IRP as pending, and
|
||||||
|
* return STATUS_PENDING to the caller
|
||||||
|
*/
|
||||||
|
(void)IoSetCancelRoutine(Irp, AfdCancelHandler);
|
||||||
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
Status = STATUS_PENDING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We were already cancelled before we were able to register our cancel routine
|
||||||
|
* so we are to call the cancel routine ourselves right here to cancel the IRP
|
||||||
|
* (which handles all the stuff we do above) and return STATUS_CANCELLED to the caller
|
||||||
|
*/
|
||||||
|
AfdCancelHandler(IoGetCurrentIrpStackLocation(Irp)->DeviceObject,
|
||||||
|
Irp);
|
||||||
|
Status = STATUS_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock( FCB );
|
||||||
return STATUS_PENDING;
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,7 +258,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
AFD_DbgPrint(MID_TRACE,
|
AFD_DbgPrint(MID_TRACE,
|
||||||
("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
|
("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
|
||||||
|
|
||||||
DbgPrint("[AfdCreate] Created socket\n");
|
DbgPrint("[AFD, AfdCreate] Called\n");
|
||||||
|
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
FileObject = IrpSp->FileObject;
|
FileObject = IrpSp->FileObject;
|
||||||
|
@ -368,6 +368,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
|
||||||
|
|
||||||
|
DbgPrint("[AFD, AfdCreate] Leaving. Status = 0x%x\n");
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,10 +385,12 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
DbgPrint("[AFD, AfdCleanupSocket] Called\n");
|
DbgPrint("[AFD, AfdCleanupSocket] Called\n");
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp);
|
if ( !SocketAcquireStateLock( FCB ) )
|
||||||
|
return LostSocket(Irp);
|
||||||
|
|
||||||
for (Function = 0; Function < MAX_FUNCTIONS; Function++)
|
for (Function = 0; Function < MAX_FUNCTIONS; Function++)
|
||||||
{
|
{
|
||||||
|
/* 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])
|
||||||
{
|
{
|
||||||
|
@ -415,15 +419,18 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
UINT i;
|
UINT i;
|
||||||
PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
|
PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS];
|
||||||
|
PAFD_TDI_OBJECT_QELT Qelt;
|
||||||
|
PLIST_ENTRY QeltEntry;
|
||||||
|
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE,
|
AFD_DbgPrint(MID_TRACE,
|
||||||
("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
|
("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
|
||||||
DbgPrint("[AfdCloseSocket] Called\n");
|
DbgPrint("[AFD, AfdCloseSocket] Called\n");
|
||||||
|
|
||||||
if( !SocketAcquireStateLock( FCB ) )
|
if( !SocketAcquireStateLock( FCB ) )
|
||||||
return STATUS_FILE_CLOSED;
|
return STATUS_FILE_CLOSED;
|
||||||
|
|
||||||
DbgPrint("[AfdCloseSocket] Setting closed state\n");
|
DbgPrint("[AFD, AfdCloseSocket] Setting closed state\n");
|
||||||
|
|
||||||
FCB->State = SOCKET_STATE_CLOSED;
|
FCB->State = SOCKET_STATE_CLOSED;
|
||||||
FCB->PollState = AFD_EVENT_CLOSE;
|
FCB->PollState = AFD_EVENT_CLOSE;
|
||||||
|
@ -435,7 +442,8 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
InFlightRequest[2] = &FCB->SendIrp;
|
InFlightRequest[2] = &FCB->SendIrp;
|
||||||
InFlightRequest[3] = &FCB->ConnectIrp;
|
InFlightRequest[3] = &FCB->ConnectIrp;
|
||||||
|
|
||||||
/* Cancel our pending requests */
|
/* Cancel our pending _In Flight_ IRPs
|
||||||
|
That is IRPs from AFD -> tcpip*/
|
||||||
for( i = 0; i < IN_FLIGHT_REQUESTS; i++ )
|
for( i = 0; i < IN_FLIGHT_REQUESTS; i++ )
|
||||||
{
|
{
|
||||||
if( InFlightRequest[i]->InFlightRequest )
|
if( InFlightRequest[i]->InFlightRequest )
|
||||||
|
@ -448,6 +456,24 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
|
|
||||||
KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
|
KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
|
||||||
|
|
||||||
|
ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_CONNECT]));
|
||||||
|
ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]));
|
||||||
|
ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]));
|
||||||
|
ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_PREACCEPT]));
|
||||||
|
|
||||||
|
while (!IsListEmpty(&FCB->PendingConnections))
|
||||||
|
{
|
||||||
|
QeltEntry = RemoveHeadList(&FCB->PendingConnections);
|
||||||
|
Qelt = CONTAINING_RECORD(QeltEntry, AFD_TDI_OBJECT_QELT, ListEntry);
|
||||||
|
|
||||||
|
/* We have to close all pending connections or the listen won't get closed */
|
||||||
|
TdiDisassociateAddressFile(Qelt->Object.Object);
|
||||||
|
ObDereferenceObject(Qelt->Object.Object);
|
||||||
|
ZwClose(Qelt->Object.Handle);
|
||||||
|
|
||||||
|
ExFreePool(Qelt);
|
||||||
|
}
|
||||||
|
|
||||||
SocketStateUnlock( FCB );
|
SocketStateUnlock( FCB );
|
||||||
|
|
||||||
if( FCB->EventSelect )
|
if( FCB->EventSelect )
|
||||||
|
@ -489,7 +515,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
if( FCB->Connection.Object )
|
if( FCB->Connection.Object )
|
||||||
{
|
{
|
||||||
TdiDisassociateAddressFile(FCB->Connection.Object);
|
TdiDisassociateAddressFile(FCB->Connection.Object);
|
||||||
ObDereferenceObject(FCB->Connection.Object);
|
ObDereferenceObject(FCB->Connection.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( FCB->AddressFile.Object )
|
if( FCB->AddressFile.Object )
|
||||||
|
@ -499,7 +525,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
|
if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
DbgPrint("[AfdCloseSocket] INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object);
|
DbgPrint("[AFD, AfdCloseSocket] INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +533,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
{
|
{
|
||||||
if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
|
if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
DbgPrint("[AfdCloseSocket] INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object);
|
DbgPrint("[AFD, AfdCloseSocket] INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +547,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
|
||||||
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
|
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
|
||||||
|
|
||||||
AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
|
AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
|
||||||
DbgPrint("[AfdCloseSocket] Leaving\n");
|
DbgPrint("[AFD, AfdCloseSocket] Leaving\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -793,6 +819,33 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return (Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CleanupPendingIrp(PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
|
||||||
|
{
|
||||||
|
PAFD_RECV_INFO RecvReq;
|
||||||
|
PAFD_SEND_INFO SendReq;
|
||||||
|
PAFD_POLL_INFO PollReq;
|
||||||
|
|
||||||
|
if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV ||
|
||||||
|
IrpSp->MajorFunction == IRP_MJ_READ)
|
||||||
|
{
|
||||||
|
RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
||||||
|
}
|
||||||
|
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
|
||||||
|
IrpSp->MajorFunction == IRP_MJ_WRITE)
|
||||||
|
{
|
||||||
|
SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
||||||
|
}
|
||||||
|
else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
|
||||||
|
{
|
||||||
|
PollReq = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
ZeroEvents(PollReq->Handles, PollReq->HandleCount);
|
||||||
|
SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
|
@ -800,39 +853,46 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PAFD_FCB FCB = FileObject->FsContext;
|
PAFD_FCB FCB = FileObject->FsContext;
|
||||||
UINT Function;
|
ULONG Function, IoctlCode;
|
||||||
PAFD_RECV_INFO RecvReq;
|
|
||||||
PAFD_SEND_INFO SendReq;
|
|
||||||
PLIST_ENTRY CurrentEntry;
|
|
||||||
PIRP CurrentIrp;
|
PIRP CurrentIrp;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PAFD_ACTIVE_POLL Poll;
|
PAFD_ACTIVE_POLL Poll;
|
||||||
PAFD_POLL_INFO PollReq;
|
|
||||||
|
|
||||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
|
|
||||||
if (!SocketAcquireStateLock(FCB))
|
if (!SocketAcquireStateLock(FCB))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
switch (IrpSp->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_READ:
|
||||||
|
IoctlCode = IOCTL_AFD_RECV;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
IoctlCode = IOCTL_AFD_SEND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT(FALSE);
|
||||||
|
SocketStateUnlock(FCB);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT(IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
|
switch (IoctlCode)
|
||||||
|
|
||||||
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
|
|
||||||
{
|
{
|
||||||
case IOCTL_AFD_RECV:
|
case IOCTL_AFD_RECV:
|
||||||
RecvReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
|
||||||
UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, FALSE);
|
|
||||||
/* Fall through */
|
|
||||||
|
|
||||||
case IOCTL_AFD_RECV_DATAGRAM:
|
case IOCTL_AFD_RECV_DATAGRAM:
|
||||||
Function = FUNCTION_RECV;
|
Function = FUNCTION_RECV;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_AFD_SEND:
|
case IOCTL_AFD_SEND:
|
||||||
SendReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
|
||||||
UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
|
|
||||||
/* Fall through */
|
|
||||||
|
|
||||||
case IOCTL_AFD_SEND_DATAGRAM:
|
case IOCTL_AFD_SEND_DATAGRAM:
|
||||||
Function = FUNCTION_SEND;
|
Function = FUNCTION_SEND;
|
||||||
break;
|
break;
|
||||||
|
@ -852,14 +912,13 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
while (CurrentEntry != &DeviceExt->Polls)
|
while (CurrentEntry != &DeviceExt->Polls)
|
||||||
{
|
{
|
||||||
Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry);
|
Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry);
|
||||||
CurrentIrp = Poll->Irp;
|
|
||||||
PollReq = CurrentIrp->AssociatedIrp.SystemBuffer;
|
|
||||||
|
|
||||||
if (CurrentIrp == Irp)
|
if (Irp == Poll->Irp)
|
||||||
{
|
{
|
||||||
ZeroEvents(PollReq->Handles, PollReq->HandleCount);
|
CleanupPendingIrp(Irp, IrpSp, Poll);
|
||||||
SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED);
|
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
|
||||||
break;
|
SocketStateUnlock(FCB);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -869,8 +928,9 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
|
KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
|
||||||
|
|
||||||
/* IRP already completed by SignalSocket */
|
|
||||||
SocketStateUnlock(FCB);
|
SocketStateUnlock(FCB);
|
||||||
|
|
||||||
|
DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -887,7 +947,9 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
if (CurrentIrp == Irp)
|
if (CurrentIrp == Irp)
|
||||||
{
|
{
|
||||||
RemoveEntryList(CurrentEntry);
|
RemoveEntryList(CurrentEntry);
|
||||||
break;
|
CleanupPendingIrp(Irp, IrpSp, NULL);
|
||||||
|
UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -895,7 +957,9 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
|
SocketStateUnlock(FCB);
|
||||||
|
|
||||||
|
DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID NTAPI
|
static VOID NTAPI
|
||||||
|
|
|
@ -185,9 +185,12 @@ static NTSTATUS NTAPI PacketSocketSendComplete
|
||||||
FCB->SendIrp.InFlightRequest = NULL;
|
FCB->SendIrp.InFlightRequest = NULL;
|
||||||
/* Request is not in flight any longer */
|
/* Request is not in flight any longer */
|
||||||
|
|
||||||
FCB->PollState |= AFD_EVENT_SEND;
|
if (Irp->IoStatus.Status == STATUS_SUCCESS)
|
||||||
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
|
{
|
||||||
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
FCB->PollState |= AFD_EVENT_SEND;
|
||||||
|
FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
|
||||||
|
PollReeval( FCB->DeviceExt, FCB->FileObject );
|
||||||
|
}
|
||||||
|
|
||||||
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
if( FCB->State == SOCKET_STATE_CLOSED ) {
|
||||||
/* Cleanup our IRP queue because the FCB is being destroyed */
|
/* Cleanup our IRP queue because the FCB is being destroyed */
|
||||||
|
|
|
@ -647,21 +647,22 @@ NTSTATUS DispTdiListen(
|
||||||
* when a new connection arrives. */
|
* when a new connection arrives. */
|
||||||
/* The important thing to note here is that the irp we'll complete belongs
|
/* The important thing to note here is that the irp we'll complete belongs
|
||||||
* to the socket to be accepted onto, not the listener */
|
* to the socket to be accepted onto, not the listener */
|
||||||
if( NT_SUCCESS(Status) && !Connection->AddressFile->Listener )
|
if ( NT_SUCCESS(Status) && !Connection->AddressFile->Listener )
|
||||||
{
|
{
|
||||||
Connection->AddressFile->Listener = TCPAllocateConnectionEndpoint( NULL );
|
Connection->AddressFile->Listener = TCPAllocateConnectionEndpoint( NULL );
|
||||||
|
|
||||||
if( !Connection->AddressFile->Listener )
|
if ( !Connection->AddressFile->Listener )
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
|
|
||||||
if( NT_SUCCESS(Status) ) {
|
if ( NT_SUCCESS(Status) )
|
||||||
|
{
|
||||||
Connection->AddressFile->Listener->AddressFile =
|
Connection->AddressFile->Listener->AddressFile =
|
||||||
Connection->AddressFile;
|
Connection->AddressFile;
|
||||||
|
|
||||||
Status = TCPSocket( Connection->AddressFile->Listener,
|
Status = TCPSocket( Connection->AddressFile->Listener,
|
||||||
Connection->AddressFile->Family,
|
Connection->AddressFile->Family,
|
||||||
SOCK_STREAM,
|
SOCK_STREAM,
|
||||||
Connection->AddressFile->Protocol );
|
Connection->AddressFile->Protocol );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( NT_SUCCESS(Status) )
|
if ( NT_SUCCESS(Status) )
|
||||||
|
|
|
@ -239,6 +239,7 @@ NTSTATUS FileOpenAddress(
|
||||||
PADDRESS_FILE AddrFile;
|
PADDRESS_FILE AddrFile;
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
|
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
|
||||||
|
DbgPrint("[TCPIP, FileOpenAddress] Called. Proto %d\n", Protocol);
|
||||||
|
|
||||||
AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE),
|
AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE),
|
||||||
ADDR_FILE_TAG);
|
ADDR_FILE_TAG);
|
||||||
|
@ -359,6 +360,7 @@ NTSTATUS FileOpenAddress(
|
||||||
&AddressFileListLock);
|
&AddressFileListLock);
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||||
|
DbgPrint("[TCPIP, FileOpenAddress] Leaving\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -377,6 +379,8 @@ NTSTATUS FileCloseAddress(
|
||||||
PADDRESS_FILE AddrFile = Request->Handle.AddressHandle;
|
PADDRESS_FILE AddrFile = Request->Handle.AddressHandle;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
DbgPrint("[TCPIP, FileCloseAddress] Called\n");
|
||||||
|
|
||||||
if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER;
|
if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
LockObject(AddrFile, &OldIrql);
|
LockObject(AddrFile, &OldIrql);
|
||||||
|
@ -393,6 +397,7 @@ NTSTATUS FileCloseAddress(
|
||||||
DereferenceObject(AddrFile);
|
DereferenceObject(AddrFile);
|
||||||
|
|
||||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||||
|
DbgPrint("[TCPIP, FileCloseAddress] Leaving\n");
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,43 +260,50 @@ NTSTATUS TiCloseFileObject(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IrpSp;
|
PIO_STACK_LOCATION IrpSp;
|
||||||
PTRANSPORT_CONTEXT Context;
|
PTRANSPORT_CONTEXT Context;
|
||||||
TDI_REQUEST Request;
|
TDI_REQUEST Request;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
DbgPrint("[TCPIP, TiCloseFileObject] Called\n");
|
||||||
Context = IrpSp->FileObject->FsContext;
|
|
||||||
if (!Context) {
|
|
||||||
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
case TDI_TRANSPORT_ADDRESS_FILE:
|
Context = IrpSp->FileObject->FsContext;
|
||||||
Request.Handle.AddressHandle = Context->Handle.AddressHandle;
|
if (!Context)
|
||||||
Status = FileCloseAddress(&Request);
|
{
|
||||||
break;
|
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
case TDI_CONNECTION_FILE:
|
switch ((ULONG_PTR)IrpSp->FileObject->FsContext2)
|
||||||
Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
|
{
|
||||||
Status = FileCloseConnection(&Request);
|
case TDI_TRANSPORT_ADDRESS_FILE:
|
||||||
break;
|
DbgPrint("[TCPIP, TiCloseFileObject] Closing address file\n");
|
||||||
|
Request.Handle.AddressHandle = Context->Handle.AddressHandle;
|
||||||
|
Status = FileCloseAddress(&Request);
|
||||||
|
break;
|
||||||
|
|
||||||
case TDI_CONTROL_CHANNEL_FILE:
|
case TDI_CONNECTION_FILE:
|
||||||
Request.Handle.ControlChannel = Context->Handle.ControlChannel;
|
Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
|
||||||
Status = FileCloseControlChannel(&Request);
|
Status = FileCloseConnection(&Request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case TDI_CONTROL_CHANNEL_FILE:
|
||||||
DbgPrint("Unknown type %d\n", (ULONG_PTR)IrpSp->FileObject->FsContext2);
|
Request.Handle.ControlChannel = Context->Handle.ControlChannel;
|
||||||
Status = STATUS_INVALID_PARAMETER;
|
Status = FileCloseControlChannel(&Request);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
default:
|
||||||
|
DbgPrint("Unknown type %d\n", (ULONG_PTR)IrpSp->FileObject->FsContext2);
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return Irp->IoStatus.Status;
|
Irp->IoStatus.Status = Status;
|
||||||
|
|
||||||
|
DbgPrint("[TCPIP, TiCloseFileObject] Leaving. Status = 0x%x\n", Status);
|
||||||
|
|
||||||
|
return Irp->IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue