Exemplo n.º 1
0
static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
                               PIRP Irp,
                               PFILE_OBJECT NewFileObject,
                               PAFD_TDI_OBJECT_QELT Qelt ) {
    PAFD_FCB FCB = NewFileObject->FsContext;
    NTSTATUS Status;

    UNREFERENCED_PARAMETER(DeviceExt);

    if( !SocketAcquireStateLock( FCB ) )
        return LostSocket( Irp );

    /* Transfer the connection to the new socket, launch the opening read */
    AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %p)\n", FCB));

    FCB->Connection = Qelt->Object;

    if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
    FCB->RemoteAddress =
        TaCopyTransportAddress( Qelt->ConnInfo->RemoteAddress );

    if( !FCB->RemoteAddress )
        Status = STATUS_NO_MEMORY;
    else
        Status = MakeSocketIntoConnection( FCB );

    if (NT_SUCCESS(Status))
        Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, FCB->RemoteAddress);

    if (NT_SUCCESS(Status))
        Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, FCB->RemoteAddress);

    return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
}
Exemplo n.º 2
0
NTSTATUS NTAPI
AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
              PIO_STACK_LOCATION IrpSp) {
    NTSTATUS Status = STATUS_SUCCESS;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PAFD_FCB FCB = FileObject->FsContext;
    PAFD_BIND_DATA BindReq;
    HANDLE UserHandle = NULL;

    UNREFERENCED_PARAMETER(DeviceObject);

    AFD_DbgPrint(MID_TRACE,("Called\n"));

    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
    if( !(BindReq = LockRequest( Irp, IrpSp, FALSE, NULL )) )
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
                                       Irp, 0 );

    if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
    FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );

    if( FCB->LocalAddress )
        Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
                                         FCB->LocalAddress );

    if( NT_SUCCESS(Status) )
        Status = WarmSocketForBind( FCB, BindReq->ShareType );
    AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));

    if (NT_SUCCESS(Status))
    {
        Status = ObOpenObjectByPointer(FCB->AddressFile.Object,
                                       0,
                                       NULL,
                                       MAXIMUM_ALLOWED,
                                       *IoFileObjectType,
                                       Irp->RequestorMode,
                                       &UserHandle);
        if (NT_SUCCESS(Status))
            FCB->State = SOCKET_STATE_BOUND;
    }

    /* MSAFD relies on us returning the address file handle in the IOSB */
    return UnlockAndMaybeComplete( FCB, Status, Irp,
                                   (ULONG_PTR)UserHandle);
}
Exemplo n.º 3
0
NTSTATUS NTAPI
PacketSocketRecvComplete(
        PDEVICE_OBJECT DeviceObject,
        PIRP Irp,
        PVOID Context ) {
    NTSTATUS Status = STATUS_SUCCESS;
    PAFD_FCB FCB = Context;
    PIRP NextIrp;
    PIO_STACK_LOCATION NextIrpSp;
    PLIST_ENTRY ListEntry;
    PAFD_RECV_INFO RecvReq;
    PAFD_STORED_DATAGRAM DatagramRecv;
    UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM );
    PLIST_ENTRY NextIrpEntry, DatagramRecvEntry;

    UNREFERENCED_PARAMETER(DeviceObject);

    AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));

    if( !SocketAcquireStateLock( FCB ) )
        return STATUS_FILE_CLOSED;

    ASSERT(FCB->ReceiveIrp.InFlightRequest == Irp);
    FCB->ReceiveIrp.InFlightRequest = NULL;

    if( FCB->State == SOCKET_STATE_CLOSED ) {
        /* Cleanup our IRP queue because the FCB is being destroyed */
        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
            NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
            NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
            NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
            RecvReq = GetLockedData(NextIrp, NextIrpSp);
            NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
            NextIrp->IoStatus.Information = 0;
            UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp));
            if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
            (void)IoSetCancelRoutine(NextIrp, NULL);
            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
        }

        /* Free all items on the datagram list */
        while( !IsListEmpty( &FCB->DatagramList ) ) {
               DatagramRecvEntry = RemoveHeadList(&FCB->DatagramList);
               DatagramRecv = CONTAINING_RECORD(DatagramRecvEntry, AFD_STORED_DATAGRAM, ListEntry);
               ExFreePool( DatagramRecv->Address );
               ExFreePool( DatagramRecv );
        }

        SocketStateUnlock( FCB );
        return STATUS_FILE_CLOSED;
    }

    if (Irp->IoStatus.Status != STATUS_SUCCESS)
    {
        SocketStateUnlock(FCB);
        return Irp->IoStatus.Status;
    }

    if (FCB->TdiReceiveClosed)
    {
        SocketStateUnlock(FCB);
        return STATUS_FILE_CLOSED;
    }

    DatagramRecv = ExAllocatePool( NonPagedPool, DGSize );

    if( DatagramRecv ) {
        DatagramRecv->Len = Irp->IoStatus.Information;
        RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window,
                       DatagramRecv->Len );
        AFD_DbgPrint(MID_TRACE,("Received (A %p)\n",
                                FCB->AddressFrom->RemoteAddress));
        DatagramRecv->Address =
            TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress );

        if( !DatagramRecv->Address ) Status = STATUS_NO_MEMORY;

    } else Status = STATUS_NO_MEMORY;

    if( !NT_SUCCESS( Status ) ) {
        if( DatagramRecv ) ExFreePool( DatagramRecv );
        SocketStateUnlock( FCB );
        return Status;
    } else {
        FCB->Recv.Content += DatagramRecv->Len;
        InsertTailList( &FCB->DatagramList, &DatagramRecv->ListEntry );
    }

    /* Satisfy as many requests as we can */

    while( !IsListEmpty( &FCB->DatagramList ) &&
           !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
        AFD_DbgPrint(MID_TRACE,("Looping trying to satisfy request\n"));
        ListEntry = RemoveHeadList( &FCB->DatagramList );
        DatagramRecv = CONTAINING_RECORD( ListEntry, AFD_STORED_DATAGRAM,
                                          ListEntry );
        ListEntry = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_RECV] );
        NextIrp = CONTAINING_RECORD( ListEntry, IRP, Tail.Overlay.ListEntry );
        NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
        RecvReq = GetLockedData(NextIrp, NextIrpSp);

        AFD_DbgPrint(MID_TRACE,("RecvReq: %p, DatagramRecv: %p\n",
                                RecvReq, DatagramRecv));

        AFD_DbgPrint(MID_TRACE,("Satisfying\n"));
        Status = SatisfyPacketRecvRequest
        ( FCB, NextIrp, DatagramRecv,
         (PUINT)&NextIrp->IoStatus.Information );

        if (RecvReq->TdiFlags & TDI_RECEIVE_PEEK)
        {
            InsertHeadList(&FCB->DatagramList,
                           &DatagramRecv->ListEntry);
        }

        AFD_DbgPrint(MID_TRACE,("Unlocking\n"));
        UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, NextIrpSp) );
        if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );

        AFD_DbgPrint(MID_TRACE,("Completing\n"));
        (void)IoSetCancelRoutine(NextIrp, NULL);
        NextIrp->IoStatus.Status = Status;

        IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
    }

    if( !IsListEmpty( &FCB->DatagramList ) && IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]) ) {
        AFD_DbgPrint(MID_TRACE,("Signalling\n"));
        FCB->PollState |= AFD_EVENT_RECEIVE;
        FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS;
        PollReeval( FCB->DeviceExt, FCB->FileObject );
    } else
        FCB->PollState &= ~AFD_EVENT_RECEIVE;

    if( NT_SUCCESS(Irp->IoStatus.Status) ) {
        /* Now relaunch the datagram request */
        Status = TdiReceiveDatagram
            ( &FCB->ReceiveIrp.InFlightRequest,
              FCB->AddressFile.Object,
              0,
              FCB->Recv.Window,
              FCB->Recv.Size,
              FCB->AddressFrom,
              &FCB->ReceiveIrp.Iosb,
              PacketSocketRecvComplete,
              FCB );
    }

    SocketStateUnlock( FCB );

    return STATUS_SUCCESS;
}
Exemplo n.º 4
0
/* Return the socket object for ths request only if it is a connected or
   stream type. */
NTSTATUS
NTAPI
AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                       PIO_STACK_LOCATION IrpSp) {
    NTSTATUS Status = STATUS_INVALID_PARAMETER;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PAFD_FCB FCB = FileObject->FsContext;
    PAFD_CONNECT_INFO ConnectReq;
    AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB));

    UNREFERENCED_PARAMETER(DeviceObject);

    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
    if( !(ConnectReq = LockRequest( Irp, IrpSp, FALSE, NULL )) )
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
                                       0 );

    AFD_DbgPrint(MID_TRACE,("Connect request:\n"));
#if 0
    OskitDumpBuffer
        ( (PCHAR)ConnectReq,
          IrpSp->Parameters.DeviceIoControl.InputBufferLength );
#endif

   if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
   {
        if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
        FCB->RemoteAddress =
            TaCopyTransportAddress( &ConnectReq->RemoteAddress );

        if( !FCB->RemoteAddress )
            Status = STATUS_NO_MEMORY;
        else
            Status = STATUS_SUCCESS;

        return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
   }

    switch( FCB->State ) {
    case SOCKET_STATE_CONNECTED:
        Status = STATUS_SUCCESS;
        break;

    case SOCKET_STATE_CONNECTING:
        return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );

    case SOCKET_STATE_CREATED:
        if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
        FCB->LocalAddress =
            TaBuildNullTransportAddress( ConnectReq->RemoteAddress.Address[0].AddressType );

        if( FCB->LocalAddress ) {
            Status = WarmSocketForBind( FCB, AFD_SHARE_WILDCARD );

            if( NT_SUCCESS(Status) )
                FCB->State = SOCKET_STATE_BOUND;
            else
                return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
        } else
            return UnlockAndMaybeComplete
                ( FCB, STATUS_NO_MEMORY, Irp, 0 );

    /* Drop through to SOCKET_STATE_BOUND */

    case SOCKET_STATE_BOUND:
        if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
        FCB->RemoteAddress =
            TaCopyTransportAddress( &ConnectReq->RemoteAddress );

        if( !FCB->RemoteAddress ) {
            Status = STATUS_NO_MEMORY;
            break;
        }

        Status = WarmSocketForConnection( FCB );

        if( !NT_SUCCESS(Status) )
            break;

    if (FCB->ConnectReturnInfo) ExFreePool(FCB->ConnectReturnInfo);
        Status = TdiBuildConnectionInfo
            ( &FCB->ConnectReturnInfo,
              &ConnectReq->RemoteAddress );

        if( NT_SUCCESS(Status) )
        {
            if (FCB->ConnectCallInfo) ExFreePool(FCB->ConnectCallInfo);
            Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo,
                                              &ConnectReq->RemoteAddress);
        }
        else break;


        if( NT_SUCCESS(Status) ) {
            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 %p\n", Irp));
        Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT );
        if (Status == STATUS_PENDING)
        {
            Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
                                FCB->Connection.Object,
                                FCB->ConnectCallInfo,
                                FCB->ConnectReturnInfo,
                                &FCB->ConnectIrp.Iosb,
                                StreamSocketConnectComplete,
                                FCB );
        }

        if (Status != STATUS_PENDING)
            FCB->State = SOCKET_STATE_BOUND;

        SocketStateUnlock(FCB);

            return Status;
        }
        break;

    default:
        AFD_DbgPrint(MIN_TRACE,("Inappropriate socket state %u for connect\n",
                                FCB->State));
        break;
    }

    return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
}