⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btsdpcon.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // retrieve the client's search request
        //
        SdpPrint(SDP_DBG_CONFIG_INFO,
                 ("L2CA_ConfigInd, we are a server, acquire and read\n"));

        status = Acquire(pReadIrp);
        if (NT_SUCCESS(status)) {
            SdpPrint(SDP_DBG_CONFIG_INFO,
                     ("L2CA_ConfigInd, acquire and read succes\n"));

            FireWmiEvent(SdpServerLogTypeConnect, btAddress, outMtu);
            ReadAsync();
        }
        else {
            SdpPrint(SDP_DBG_CONFIG_ERROR | SDP_DBG_CONFIG_WARNING,
                     ("L2CA_ConfigInd, acquire and read not successful, 0x%x\n",
                      status));
            disconnect = TRUE;
        }
    }

    return disconnect;
}

void SdpConnection::CompletePendingConnectRequests(NTSTATUS status)
{
    CList<IRP, IRP_LE_OFFSET> irps;
    KIRQL irql;

    LockState(&irql);
    while (!connectList.IsEmpty()) {
        irps.AddTail(connectList.RemoveHead());
    }
    UnlockState(irql);

    while (!irps.IsEmpty()) {
        PIRP irp = irps.RemoveHead();

        irp->IoStatus.Status = status;
        if (NT_SUCCESS(status)) {
            BthSdpConnect *pConnect;
            BthConnect *pBthConnect;

            pConnect = NULL;
            pBthConnect = NULL;

            // DJH:  remove me later
            if (IoGetCurrentIrpStackLocation(irp)->
                    Parameters.DeviceIoControl.OutputBufferLength ==
                sizeof(BthSdpConnect)) {
                pConnect = (BthSdpConnect*) irp->AssociatedIrp.SystemBuffer;

                RtlZeroMemory(pConnect, sizeof(BthSdpConnect));
                pConnect->hConnection = hConnection;
                irp->IoStatus.Information = sizeof(BthSdpConnect);
            }
            else {
                pBthConnect = (BthConnect*) irp->AssociatedIrp.SystemBuffer;

                RtlZeroMemory(pBthConnect, sizeof(BthConnect));
                pBthConnect->hConnection = hConnection;
                irp->IoStatus.Information = sizeof(BthConnect);
            }

            AddFileObject(IoGetCurrentIrpStackLocation(irp)->FileObject);
        }
        else {
            irp->IoStatus.Information = 0;
        }

        SdpPrint(SDP_DBG_CONFIG_INFO,
                 ("Completing connect request %p with status 0x%x\n",
                  irp, status));

        Release(irp);

        IoCompleteRequest(irp, IO_NO_INCREMENT);
    }
}

VOID
SdpConnection::_QueueCancelRoutine(
    PVOID Context,
    PIRP Irp
    )
{
    ((SdpConnection *) Context)->Release(Irp);
}

#endif // UNDER_CE


NTSTATUS
SdpConnection::SendServiceSearchRequest(
    PIRP pIrp
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    , SdpServiceSearch *pSearch
#endif
    )
{
//  BthSdpServiceSearchRequest *pSearch;
//  PIO_STACK_LOCATION stack;
    PSDP_NODE pTree = NULL;
    PUCHAR stream = NULL, tmpStream;
    ULONG streamSize = 0;
    NTSTATUS status;
//  ULONG outlen;
    USHORT maxHandles, totalSize;
    UCHAR maxUuids;

    ContinuationState cs;
    SdpPDU pdu;

#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    maxHandles = pSearch->cMaxHandles;
    maxUuids   = (UCHAR) pSearch->cUUIDs;
    pTree = SdpInterface::CreateServiceSearchTree(pSearch->uuids,maxUuids);
#else
    stack = IoGetCurrentIrpStackLocation(pIrp);

    maxHandles = (USHORT)
        (stack->Parameters.DeviceIoControl.OutputBufferLength / sizeof(ULONG));

    maxUuids = GetMaxUuidsFromIrp(pIrp);

    pSearch = (BthSdpServiceSearchRequest *) pIrp->AssociatedIrp.SystemBuffer;
    pTree = SdpInterface::CreateServiceSearchTree(pSearch->uuids, maxUuids);
#endif
    if (pTree == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Error;
    }

    status = SdpStreamFromTreeEx(pTree,
                                 &stream,
                                 &streamSize,
                                 sizeof(SdpPDU),
                                 sizeof(maxHandles) + sizeof(cs));

    //
    // Our initial request does not have a continuation state, BUT if we get
    // a partial response, we need to send  request w/a cont state, so just
    // alloc room for it now
    //
    totalSize = sizeof(SdpPDU) +
                (USHORT) streamSize +
                sizeof(maxHandles) +
                sizeof(cs.size);

    SdpFreeTree(pTree);
    pTree = NULL;

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

    if (totalSize > outMtu) {
        //
        // Can't xmit the request, sigh
        //
        status = STATUS_UNSUCCESSFUL;
        goto Error;
    }

    pdu.pduId = SdpPDU_ServiceSearchRequest; 
    pdu.transactionId = transactionId++;
    pdu.parameterLength = totalSize - sizeof(SdpPDU); 

    //
    // Write the PDU, then skip over the already written stream
    //
    tmpStream = pdu.Write(stream);

    //
    // increment past already writen search pattern
    //
    tmpStream += streamSize;

    maxHandles = RtlUshortByteSwap(maxHandles);
    RtlCopyMemory(tmpStream, &maxHandles, sizeof(maxHandles));
    tmpStream += sizeof(maxHandles);
    
    ASSERT(cs.size == 0);
    cs.Write(tmpStream);

#if DBG
    tmpStream += cs.GetTotalSize();
    ASSERT((tmpStream - stream) == totalSize);
#endif 

    SdpPrint(SDP_DBG_CLIENT_INFO, ("sending initial request for service search\n"));
             
    return SendInitialRequestToServer(pIrp, stream, totalSize, pdu.pduId);

Error:
    if (pTree) {
        SdpFreeTree(pTree);
    }

    if (stream) {
        ExFreePool(stream);
    }

    ReleaseAndProcessNextRequest(pIrp);

    return status;
}

NTSTATUS
SdpConnection::SendAttributeSearchRequest(
    PIRP pIrp
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    , SdpAttributeSearch *pSearch
#endif
    )
{
//  BthSdpAttributeSearchRequest *pSearch;
    PSDP_NODE pTree = NULL;
    PUCHAR stream = NULL, tmpStream;
    NTSTATUS status;
    ULONG streamSize = 0, recordHandle; // maxRange
    USHORT totalSize;
    
    SdpPDU pdu;

    ContinuationState cs;
    USHORT maxByteCount;

#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    recordHandle = RtlUlongByteSwap(pSearch->recordHandle);

    pTree = SdpInterface::CreateAttributeSearchTree(pSearch->range,
                           pSearch->numAttributes);
#else
    maxRange = GetMaxRangeFromIrp(pIrp);
    pSearch = (BthSdpAttributeSearchRequest *) pIrp->AssociatedIrp.SystemBuffer;

    pTree = SdpInterface::CreateAttributeSearchTree(pSearch->range, maxRange);
#endif
    if (pTree == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Error;
    }

    //
    // Our initial request does not have a continuation state, BUT if we get
    // a partial response, we need to send  request w/a cont state, so just
    // alloc room for it now by allocating sizeof(cs) instead of sizeof(cs.size)
    //
    status = SdpStreamFromTreeEx(pTree,
                                 &stream,
                                 &streamSize,
                                 sizeof(SdpPDU) + sizeof(recordHandle) + sizeof(maxByteCount), 
                                 sizeof(cs));

    totalSize = sizeof(SdpPDU) +
                sizeof(recordHandle) +
                sizeof(maxByteCount) +
                (USHORT) streamSize +
                sizeof(cs.size);

    SdpFreeTree(pTree);
    pTree = NULL;

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

    if (totalSize > outMtu) {
        //
        // Can't xmit the request
        //
        status =  STATUS_UNSUCCESSFUL;
        goto Error;
    }

    // if (g_Support10B) {
    //     maxByteCount = 0xFFFF; 
    // }
    // else {
    //     maxByteCount = GetMaxByteCount(inMtu);
    // }
    maxByteCount = GetMaxByteCount(inMtu);

    pdu.pduId = SdpPDU_ServiceAttributeRequest;
    pdu.transactionId = transactionId++;
    pdu.parameterLength = totalSize - sizeof(SdpPDU);

    //
    // Write the PDU, then skip over the already written stream
    //
    tmpStream = pdu.Write(stream);


#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    // This is done at top of fcn for WinCE
    recordHandle = RtlUlongByteSwap(pSearch->recordHandle);
#endif

    RtlCopyMemory(tmpStream, &recordHandle, sizeof(recordHandle));
    tmpStream += sizeof(recordHandle);
    
    maxByteCount = RtlUshortByteSwap(maxByteCount);
    RtlCopyMemory(tmpStream, &maxByteCount, sizeof(maxByteCount));
    tmpStream += sizeof(maxByteCount);

    tmpStream += streamSize;

    ASSERT(cs.size == 0);
    cs.Write(tmpStream);

#if DBG
    tmpStream += cs.GetTotalSize();
    ASSERT((tmpStream - stream) == totalSize);
#endif // DBG

    SdpPrint(SDP_DBG_CLIENT_INFO, ("sending initial request for attribute search\n"));

    return SendInitialRequestToServer(pIrp, stream, totalSize, pdu.pduId);

Error:

    if (pTree) {
        SdpFreeTree(pTree);
    }

    if (stream) {
        ExFreePool(stream);
    }

    ReleaseAndProcessNextRequest(pIrp);

    return status;
}

NTSTATUS
SdpConnection::SendServiceSearchAttributeRequest(
    PIRP pIrp
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    , SdpServiceAttributeSearch *pSearch
#endif
    )
{
//  BthSdpServiceAttributeSearchRequest *pSearch;
    PSDP_NODE pTreeService = NULL, pTreeAttrib = NULL;
    PUCHAR stream = NULL, tmpStream;
    NTSTATUS status;
    ULONG maxRange, streamSize, serviceSize, attribSize;
    int totalSize;
    USHORT maxByteCount;
    UCHAR maxUuids;

    SdpPDU pdu;
    ContinuationState cs;

#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    ASSERT(pSearch->cUUIDs <= MAX_UUIDS_IN_QUERY);
    maxUuids = (UCHAR) pSearch->cUUIDs;
    maxRange = pSearch->numAttributes;
#else
    maxUuids = GetMaxUuidsFromIrp(pIrp);
    maxRange = GetMaxRangeFromIrp(pIrp);

    pSearch = (BthSdpServiceAttributeSearchRequest *)
        pIrp->AssociatedIrp.SystemBuffer;
#endif

    pTreeService =
        SdpInterface::CreateServiceSearchTree(pSearch->uuids, maxUuids);

    if (pTreeService == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Error;
    }

    pTreeAttrib = SdpInterface::CreateAttributeSearchTree(pSearch->range, maxRange);
    if (pTreeAttrib == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Error;
    }

    status = ComputeNodeListSize(
        ListEntryToSdpNode(SdpNode_GetNextEntry(pTreeService)),
        &serviceSize);

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

    status = ComputeNodeListSize(
        ListEntryToSdpNode(SdpNode_GetNextEntry(pTreeAttrib)),
        &attribSize);

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

    status = SdpStreamFromTreeEx(pTreeService,
                                 &stream,
                                 &streamSize,
                                 sizeof(SdpPDU),    
                                 sizeof(maxByteCount) + attribSize + sizeof(cs));

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

    status = 
        NodeToStream(
            ListEntryToSdpNode(SdpNode_GetNextEntry(pTreeAttrib)),
            stream + sizeof(SdpPDU) + serviceSize + sizeof(maxByteCount) );

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

    SdpFreeTree(pTreeService);
    SdpFreeTree(pTreeAttrib);

    pTreeService = NULL;
    pTreeAttrib = NULL;

    totalSize = sizeof(SdpPDU)        +
                serviceSize           +
                sizeof(maxByteCount)  +
                attribSize            +
                sizeof(cs.size);

    if (totalSize > outMtu) {
        status = STATUS_UNSUCCESSFUL;
        goto Error;
    }

    // if (g_Support10B) {
    //     maxByteCount = 0xFFFF;
    // }
    // else {
    //     maxByteCount = GetMaxByteCount(inMtu);
    // }
    maxByteCount = GetMaxByteCount(inMtu);

    pdu.pduId = SdpPDU_ServiceSearchAttributeRequest;
    pdu.transactionId = transactionId++;
    pdu.parameterLength = (USHORT) (totalSize - sizeof(SdpPDU));

    tmpStream = pdu.Write(stream);

    //
    // service search pattern was written out by the call to SdpStreamFromTreeEx
    //
    tmpStream += serviceSize;

    maxByteCount = RtlUshortByteSwap(maxByteCount);
    RtlCopyMemory(tmpStream, &maxByteCount, sizeof(maxByteCount));
    tmpStream += sizeof(maxByteCount);

    //
    // AttributeIDList was written out by the call to NodeToStream 
    //
    tmpStream += attribSize;

    ASSERT(cs.size == 0);
    cs.Write(tmpStream);

#if DBG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -