Beispiel #1
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 );
}
Beispiel #2
0
NTSTATUS NTAPI
AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                         PIO_STACK_LOCATION IrpSp) {
    NTSTATUS Status = STATUS_SUCCESS;
    PTDI_CONNECTION_INFORMATION TargetAddress;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PAFD_FCB FCB = FileObject->FsContext;
    PAFD_SEND_INFO_UDP SendReq;
    KPROCESSOR_MODE LockMode;

    UNREFERENCED_PARAMETER(DeviceObject);

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

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

    FCB->EventSelectDisabled &= ~AFD_EVENT_SEND;

    /* Check that the socket is bound */
    if( FCB->State != SOCKET_STATE_BOUND &&
            FCB->State != SOCKET_STATE_CREATED)
    {
        AFD_DbgPrint(MIN_TRACE,("Invalid socket state\n"));
        return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
    }

    if (FCB->SendClosed)
    {
        AFD_DbgPrint(MIN_TRACE,("No more sends\n"));
        return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0);
    }

    if( !(SendReq = LockRequest( Irp, IrpSp, FALSE, &LockMode )) )
        return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);

    if (FCB->State == SOCKET_STATE_CREATED)
    {
        if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
        FCB->LocalAddress =
            TaBuildNullTransportAddress( ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.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 );
    }

    SendReq->BufferArray = LockBuffers( SendReq->BufferArray,
                                        SendReq->BufferCount,
                                        NULL, NULL,
                                        FALSE, FALSE, LockMode );

    if( !SendReq->BufferArray )
        return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
                                       Irp, 0 );

    AFD_DbgPrint
    (MID_TRACE,("RemoteAddress #%d Type %u\n",
                ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)->
                TAAddressCount,
                ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)->
                Address[0].AddressType));

    Status = TdiBuildConnectionInfo( &TargetAddress,
                                     ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress) );

    /* Check the size of the Address given ... */

    if( NT_SUCCESS(Status) ) {
        FCB->PollState &= ~AFD_EVENT_SEND;

        Status = QueueUserModeIrp(FCB, Irp, FUNCTION_SEND);
        if (Status == STATUS_PENDING)
        {
            TdiSendDatagram(&FCB->SendIrp.InFlightRequest,
                            FCB->AddressFile.Object,
                            SendReq->BufferArray[0].buf,
                            SendReq->BufferArray[0].len,
                            TargetAddress,
                            PacketSocketSendComplete,
                            FCB);
        }

        ExFreePool(TargetAddress);

        SocketStateUnlock(FCB);

        return STATUS_PENDING;
    }
    else
    {
        UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE);
        return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
    }
}