Ejemplo n.º 1
0
NTSTATUS
BthEchoSrvConnectionStateConnected(
    WDFOBJECT ConnectionObject
    )
/*++
Routine Description:

    This routine is invoked by BthEchoSrvRemoteConnectResponseCompletion
    when connect response is completed.

    We initialize and submit continous readers in this routine.

Arguments:

    ConnectionObject - Connection object for which connect response completed

--*/
{
    PBTHECHO_CONNECTION connection;
    NTSTATUS status;

    connection = GetConnectionObjectContext(ConnectionObject);

    status = BthEchoConnectionObjectInitializeContinuousReader(
        connection,
        BthEchoSrvConnectionObjectContReaderReadCompletedCallback,
        BthEchoSrvConnectionObjectContReaderFailedCallback,
        BthEchoSampleMaxDataLength
        );

    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    status = BthEchoConnectionObjectContinuousReaderSubmitReaders(
        connection
        );

    if (!NT_SUCCESS(status))
    {
        goto exit;
    }
    
exit:    
    return status;
}
Ejemplo n.º 2
0
_Use_decl_annotations_
VOID
BthEchoEvtConnectionObjectCleanup(
    WDFOBJECT  ConnectionObject
    )
/*++

Description:

    This routine is invoked by the Framework when connection object
    gets deleted (either explicitly or implicitly because of parent
    deletion).

    Since we mark ExecutionLevel as passive for connection object we get this
    callback at passive level and can wait for stopping of continuous
    readers and for disconnect to complete.

Arguments:

    ConnectionObject - The Connection Object

Return Value:

    None

--*/
{
    PBTHECHO_CONNECTION connection = GetConnectionObjectContext(ConnectionObject);

    PAGED_CODE();
        
    BthEchoConnectionObjectWaitForAndUninitializeContinuousReader(connection);

    KeWaitForSingleObject(&connection->DisconnectEvent,
        Executive,
        KernelMode,
        FALSE,
        NULL);

    WdfObjectDelete(connection->ConnectDisconnectRequest);
}
Ejemplo n.º 3
0
__drv_sameIRQL
NTSTATUS
BthEchoCliOpenRemoteConnection(
    __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx,
    __in WDFFILEOBJECT FileObject,
    __in WDFREQUEST Request
    )
/*++

Description:

    This routine is invoked by BthEchoCliEvtDeviceFileCreate.
    In this routine we send down open channel BRB.

    This routine allocates open channel BRB. If the request
    is sent down successfully completion routine needs to free
    this BRB.
    
Arguments:

    __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx - 
    __in WDFFILEOBJECT FileObject - 
    __in WDFREQUEST Request - 

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status;
    WDFOBJECT connectionObject;    
    struct _BRB_L2CA_OPEN_CHANNEL *brb = NULL;
    PBTHECHO_CONNECTION connection = NULL;
    PBTHECHOSAMPLE_CLIENT_FILE_CONTEXT fileCtx = GetFileContext(FileObject);

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CONNECT, 
        "Connect request");        

    //
    // Create the connection object that would store information
    // about the open channel
    //
    // Set file object as the parent for this connection object
    //
    status = BthEchoConnectionObjectCreate(
        &DevCtx->Header,
        FileObject, //parent
        &connectionObject
        );

    if (!NT_SUCCESS(status))
    {
        goto exit;
    }

    connection = GetConnectionObjectContext(connectionObject);

    connection->ConnectionState = ConnectionStateConnecting;

    //
    // Get the BRB from request context and initialize it as
    // BRB_L2CA_OPEN_CHANNEL BRB
    //
    brb = (struct _BRB_L2CA_OPEN_CHANNEL *)GetRequestContext(Request);

    DevCtx->Header.ProfileDrvInterface.BthReuseBrb(
        (PBRB)brb, 
        BRB_L2CA_OPEN_CHANNEL
        );
    
    brb->Hdr.ClientContext[0] = connection;
    brb->BtAddress = DevCtx->ServerBthAddress;
    brb->Psm = fileCtx->ServerPsm;

    brb->ChannelFlags = CF_ROLE_EITHER;

    brb->ConfigOut.Flags = 0;
    brb->ConfigIn.Flags = 0;

    brb->ConfigOut.Flags |= CFG_MTU;
    brb->ConfigOut.Mtu.Max = L2CAP_DEFAULT_MTU;
    brb->ConfigOut.Mtu.Min = L2CAP_MIN_MTU;
    brb->ConfigOut.Mtu.Preferred = L2CAP_DEFAULT_MTU;

    brb->ConfigIn.Flags = CFG_MTU;
    brb->ConfigIn.Mtu.Max = brb->ConfigOut.Mtu.Max;
    brb->ConfigIn.Mtu.Min = brb->ConfigOut.Mtu.Min;
    brb->ConfigIn.Mtu.Preferred = brb->ConfigOut.Mtu.Max;

    //
    // Get notificaiton about remote disconnect 
    //
    brb->CallbackFlags = CALLBACK_DISCONNECT;                                                   

    brb->Callback = &BthEchoCliIndicationCallback;
    brb->CallbackContext = connection;
    brb->ReferenceObject = (PVOID) WdfDeviceWdmGetDeviceObject(DevCtx->Header.Device);
    brb->IncomingQueueDepth = 50;

    status = BthEchoSharedSendBrbAsync(
        DevCtx->Header.IoTarget,
        Request,
        (PBRB) brb,
        sizeof(*brb),
        BthEchoCliRemoteConnectCompletion,
        brb    //Context
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_CONNECT, 
            "Sending brb for opening connection failed, returning status code %!STATUS!\n", status);

        goto exit;
    }            

exit:

    if(!NT_SUCCESS(status))
    {
        if (connection)
        {
            //
            // Set the right state to facilitate debugging
            //
            connection->ConnectionState = ConnectionStateConnectFailed;            
        }

        //
        // In case of failure of this routine we will fail
        // Create which will delete file object and since connection object
        // is child of the file object, it will be deleted too
        //
    }
    
    return status;
}
Ejemplo n.º 4
0
NTSTATUS
BthEchoConnectionObjectInit(
    _In_ WDFOBJECT ConnectionObject,
    _In_ PBTHECHOSAMPLE_DEVICE_CONTEXT_HEADER DevCtxHdr
    )
/*++

Description:

    This routine initializes connection object.
    It is invoked by BthEchoConnectionObjectCreate.

Arguments:

    ConnectionObject - Object to initialize
    DevCtxHdr - Device context header

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;
    PBTHECHO_CONNECTION connection = GetConnectionObjectContext(ConnectionObject);

    
    connection->DevCtxHdr = DevCtxHdr;

    connection->ConnectionState = ConnectionStateInitialized;

    //
    // Initialize spinlock
    //
    
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = ConnectionObject;

    status = WdfSpinLockCreate(
                               &attributes,
                               &connection->ConnectionLock
                               );
    if (!NT_SUCCESS(status))
    {
        goto exit;                
    }

    //
    // Create connect/disconnect request
    //
    
    status = WdfRequestCreate(
        &attributes,
        DevCtxHdr->IoTarget,
        &connection->ConnectDisconnectRequest
        );

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    //
    // Initialize event
    //
    
    KeInitializeEvent(&connection->DisconnectEvent, NotificationEvent, TRUE);

    //
    // Initalize list entry
    //

    InitializeListHead(&connection->ConnectionListEntry);

    connection->ConnectionState = ConnectionStateInitialized;

exit:
    return status;
}