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

📄 btsdp.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 5 页
字号:

NTSTATUS
SdpInterface::VerifyServiceSearch(
    SdpQueryUuid *pUuids,
    UCHAR *pMaxUuids
    )
{
    //
    // Verify that the entries are all well formed
    //
    GUID zeroGuid;

    RtlZeroMemory(&zeroGuid, sizeof(GUID));

    UCHAR i = 0;
    for (i = 0; i < MAX_UUIDS_IN_QUERY; i++, (*pMaxUuids)++) 
    {
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
        if (0 == memcmp(&pUuids[i].u.uuid128,&zeroGuid,sizeof(GUID)))
            break;
#else
        if (RtlCompareMemory(&pUuids[i].u.uuid128,
                             &zeroGuid,
                             sizeof(GUID)) == sizeof(GUID)) {
            break;
        }
#endif
        if (pUuids[i].uuidType != SDP_ST_UUID128 &&
            pUuids[i].uuidType != SDP_ST_UUID32  &&
            pUuids[i].uuidType != SDP_ST_UUID16) {
            return STATUS_INVALID_PARAMETER;
        }
    }

    if (*pMaxUuids == 0) {
        return STATUS_INVALID_PARAMETER;
    }

    return STATUS_SUCCESS;
}

PSDP_NODE
SdpInterface::CreateServiceSearchTree(
    SdpQueryUuid *pUuids,
    UCHAR maxUuids
    )
/*++

    Given an array of SdpQueryUuids, create an SDP tree that represents the
    data within it so that later we can create a stream.
   
  --*/
{
    PSDP_NODE pTree;
    PSDP_NODE pNode, pSequence;

    pTree = SdpCreateNodeTree();
    if (pTree == NULL) {
        return NULL;
    }

    pSequence = SdpCreateNodeSequence();
    if (pSequence == NULL) {
        SdpFreeTree(pTree);
        return NULL;
    }

    SdpAppendNodeToContainerNode(pTree, pSequence);

    ULONG invalidUuid = 0;

#if UPF
    HANDLE hKey;

    if (NT_SUCCESS(BthPort_OpenKey(NULL,
                                   STR_REG_MACHINE STR_SOFTWARE_KEYW,
                                   &hKey))) {
        ULONG tmp = 0;
        if (NT_SUCCESS(QueryKeyValue(hKey,
                                     L"InvalidUUID",
                                     &tmp,
                                     sizeof(ULONG))) && tmp != 0) {
            invalidUuid = 1;
            SdpPrint(0, ("***UPF*** using an invalid UUID for search\n"));
        }

        ZwClose(hKey);
    }
#endif // UPF

    for (UCHAR i = 0; i < maxUuids; i++) {
        if (pUuids[i].uuidType == SDP_ST_UUID128) {
            pNode = SdpCreateNodeUUID128(&pUuids[i].u.uuid128);
        }
        else if (pUuids[i].uuidType == SDP_ST_UUID32) {
            if (invalidUuid) {
                pNode = SdpCreateNodeUInt32(pUuids[i].u.uuid32);
            }
            else {
                pNode = SdpCreateNodeUUID32(pUuids[i].u.uuid32);
            }
        }
        else {
            // SDP_ST_UUID16
            if (invalidUuid) {
                pNode = SdpCreateNodeUInt16(pUuids[i].u.uuid16);
            }
            else {
                pNode = SdpCreateNodeUUID16(pUuids[i].u.uuid16);
            }
        }

        if (pNode == NULL) {
            SdpFreeTree(pTree);
            pTree = NULL;
            break;
        }
        else {
            SdpAppendNodeToContainerNode(pSequence, pNode);
        }
    }

    return pTree;
}

NTSTATUS
SdpInterface::VerifyAttributeSearch(
    SdpAttributeRange *pRange,
    ULONG *pMaxRange,
    ULONG_PTR bufferLength
    )
{
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    *pMaxRange = 0;
#endif

    //
    // Must be in even mulitples of SdpAttributeRange
    //
    if ((bufferLength % sizeof(SdpAttributeRange)) != 0) {
        return STATUS_INVALID_BUFFER_SIZE;
    }

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    *pMaxRange = (ULONG) (bufferLength / sizeof(SdpAttributeRange));
#endif

    ULONG i = 0;
    USHORT minAttrib = 0;

    for ( ; i < *pMaxRange; i++) {
        if (pRange[i].maxAttribute < pRange[i].minAttribute) {
            return STATUS_INVALID_PARAMETER;
        }

        //
        // We now know that pRange[i].minAttribute <= pRange[i].maxAttribute
        // 
        if (i != 0 && pRange[i].minAttribute <= minAttrib) {
            return STATUS_INVALID_PARAMETER;
        }

        minAttrib = pRange[i].maxAttribute; 
    }

    return STATUS_SUCCESS;
}

PSDP_NODE 
SdpInterface::CreateAttributeSearchTree(
    SdpAttributeRange *pRange,
    ULONG maxRange
    )
/*++

    Given an array of SdpAttributeRange elements, convert them into an SDP tree
    so that we can later convert the tree into a stream
    
  --*/
{
    ULONG i = 0;

    PSDP_NODE pTree;
    PSDP_NODE pNode, pSequence;

    pTree = SdpCreateNodeTree();
    if (pTree == NULL) {
        return NULL;
    }

    pSequence = SdpCreateNodeSequence();
    if (pSequence == NULL) {
        SdpFreeTree(pTree);
        return NULL;
    }

    SdpAppendNodeToContainerNode(pTree, pSequence);

    for ( ; i < maxRange; i++) {
        if (pRange[i].minAttribute == pRange[i].maxAttribute) {
            pNode = SdpCreateNodeUInt16(pRange[i].minAttribute);
        }
        else {
            ULONG tmp = pRange[i].minAttribute;

            //
            // move the value into the high word
            //
            tmp <<= 16;
            pNode = SdpCreateNodeUInt32(tmp | pRange[i].maxAttribute );
       }

        if (pNode == NULL) {
            SdpFreeTree(pTree);
            pTree = NULL;
            break;
        }

        SdpAppendNodeToContainerNode(pSequence, pNode);
    }

    return pTree;
}

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
NTSTATUS
SdpInterface::AcquireConnectionInternal(
    SdpConnection *pCon,
    PVOID tag
    )
{
    if (pCon) {
        NTSTATUS status = STATUS_SUCCESS;
        KIRQL irql;

        pCon->LockState(&irql);
        if (pCon->channelState == SdpChannelStateClosed) {
            status = STATUS_DEVICE_NOT_CONNECTED;
        }
        pCon->UnlockState(irql);

        if (NT_SUCCESS(status)) {
            return pCon->Acquire(tag);
        }

        return status;
    }
    else {
        return STATUS_INVALID_PARAMETER;
    }
}

NTSTATUS
SdpInterface::AcquireConnection(
    PVOID hConnection,
    SdpConnection** ppCon,
    PVOID tag
    )
/*++

    Finds an active SdpConnection based on the handle to the connection.  If
    a valid connection is returned, it will have been Acquired with tag

  --*/
{
    NTSTATUS status;

    m_SdpConnectionList.Lock();
    *ppCon = FindConnection(hConnection);
    status = AcquireConnectionInternal(*ppCon, tag);
    m_SdpConnectionList.Unlock();

    return status;
}

NTSTATUS
SdpInterface::AcquireConnection(
    const bt_addr& btAddress,
    SdpConnection** ppCon,
    PVOID tag
    )
/*++

    Finds an active SdpConnection based on the address of the connection.  If
    a valid connection is returned, it will have been Acquired with tag

  --*/
{
    NTSTATUS status;

    m_SdpConnectionList.Lock();
    *ppCon = FindConnection(btAddress);
    status = AcquireConnectionInternal(*ppCon, tag);
    m_SdpConnectionList.Unlock();

    return status;
}

NTSTATUS SdpInterface::Connect(PIRP pIrp, ULONG_PTR& info)
{
    SdpConnection *pCon, *pConFind;
    BthSdpConnect tmpConnect, *pConnect;
    BthConnect *pBthConnect;
    PIO_STACK_LOCATION stack;
    HANDLE hConnection;
    NTSTATUS status;
    ULONG inLen, outLen;
    KIRQL irql;

    hConnection = NULL;
    stack = IoGetCurrentIrpStackLocation(pIrp);
    info = 0;
    inLen =  stack->Parameters.DeviceIoControl.InputBufferLength;
    outLen =  stack->Parameters.DeviceIoControl.OutputBufferLength;


    //
    // DJH:  remove the check for BthConnect later
    //
    CAssertF(sizeof(BthSdpConnect) != sizeof(BthConnect));
    if ((inLen != sizeof(BthSdpConnect) && outLen != sizeof(BthSdpConnect)) &&
        (inLen != sizeof(BthConnect) && outLen != sizeof(BthConnect))) {
        return STATUS_BUFFER_TOO_SMALL;
    }

    if (inLen == sizeof(BthSdpConnect)) {
        pConnect = (BthSdpConnect*) pIrp->AssociatedIrp.SystemBuffer;
    }
    else {
        pBthConnect = (BthConnect*) pIrp->AssociatedIrp.SystemBuffer;

        RtlZeroMemory(&tmpConnect, sizeof(tmpConnect));
        tmpConnect.btAddress = pBthConnect->btAddress;
        tmpConnect.fSdpConnect = 0;
        tmpConnect.requestTimeout = SDP_REQUEST_TO_DEFAULT;

        pConnect = &tmpConnect;
    }

    if ((pConnect->requestTimeout != SDP_REQUEST_TO_DEFAULT) &&
        (pConnect->requestTimeout < SDP_REQUEST_TO_MIN ||
         pConnect->requestTimeout > SDP_REQUEST_TO_MAX)) {
        return STATUS_INVALID_PARAMETER;
    }

    if (pConnect->fSdpConnect & ~SDP_CONNECT_VALID_FLAGS) {
        return STATUS_INVALID_PARAMETER;
    }

    if (pConnect->fSdpConnect & SDP_CONNECT_CACHE) {
        SdpPrint(SDP_DBG_CONFIG_WARNING,
                 ("Connect, cached searches not implemented yet!\n"));
    }

    pCon = new (NonPagedPool, SDPI_TAG) SdpConnection(m_pDevice, TRUE);
    if (pCon == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    else if (pCon->Init() == FALSE) {
        delete pCon;
        return STATUS_INSUFFICIENT_RESOURCES;
    }


    m_SdpConnectionList.Lock();

    pConFind = FindConnection(pConnect->btAddress);
    if (pConFind) {
        pConFind->Acquire(pIrp);

        SdpPrint(SDP_DBG_CONFIG_WARNING, ("Connect, found a connection\n"));
        if (pConFind->IsClient()) {
            SdpPrint(SDP_DBG_CONFIG_WARNING | SDP_DBG_CONFIG_ERROR,
                     ("Connect, connection is a client\n"));
        }
        else {
            SdpPrint(SDP_DBG_CONFIG_WARNING | SDP_DBG_CONFIG_INFO,
                     ("Connect, connection is a server\n"));
        }
    }
    else {
        SdpPrint(SDP_DBG_CONFIG_INFO, ("Connect, did not find a connection\n"));
    }

    BOOLEAN useExistingConnection = FALSE;

    status = STATUS_SUCCESS;

    if (pConFind) {
        if (pConFind->IsClient()) {
            useExistingConnection  = TRUE;
            m_SdpConnectionList.Unlock();
            if (pConFind->closing == FALSE) {
                pConFind->LockState(&irql);
                if (pConFind->channelState == SdpChannelStateConnecting) {
                    IoMarkIrpPending(pIrp);
                    pCon->connectList.AddTail(pIrp);
                    status = STATUS_PENDING;
                }
                pConFind->UnlockState(irql);

                //
                // We will complete this irp when the connection is finalized or if
                // the connection dies
                //
                if (status == STATUS_PENDING) {
                    return status;
                }

                if (pConFind->AddFileObject(stack->FileObject)) {
                    hConnection = pConFind->hConnection;
                    status = STATUS_SUCCESS;
                }
                else {
                    status = STATUS_INSUFFICIENT_RESOURCES;
                }
            }
            else {
                status = STATUS_DELETE_PENDING;
            }
        }
        else {
            pCon->btAddress = pConnect->btAddress;

            SdpPrint(SDP_DBG_CONFIG_TRACE,
                     ("Adding new server connection %p to connection list\n",
                      pCon));

            m_SdpConnectionList.AddTail(pCon);
            m_SdpConnectionList.Unlock();
        }
        pConFind->Release(pIrp);
    }
    else {
        //
        // Either there were no active connections to this address or there is a
        // client connection
        //
        pCon->btAddress = pConnect->btAddress;

        SdpPrint(SDP_DBG_CONFIG_TRACE,
                 ("Adding new client connection %p to connection list\n", pCon));

        m_SdpConnectionList.AddTail(pCon);
        m_SdpConnectionList.Unlock();
    }

    //
    // If we found a connection and it is still alive, delete our temp connection
    // object and return
    //
    if (useExistingConnection) {
        delete pCon;

        if (NT_SUCCESS(status)) {
            if (outLen == sizeof(BthSdpConnect)) {
                RtlZeroMemory(pConnect, sizeof(*pConnect));
                pConnect->hConnection = hConnection;
                info = sizeof(*pConnect);
            }
            else {
                // DJH:  remove me later
                RtlZeroMemory(pBthConnect, sizeof(*pBthConnect));
                pBthConnect->hConnection = hConnection;
                info = sizeof(*pBthConnect);
            }

⌨️ 快捷键说明

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