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

📄 btsdp.cpp

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

        SdpPrint(SDP_DBG_CONFIG_INFO,
                 ("completing piggy back connect 0x%x\n", status));

        return status;
    }

    if (pConnect->requestTimeout == SDP_REQUEST_TO_DEFAULT) {
        pCon->maxTimeout = SDP_DEFAULT_TIMEOUT;
    }
    else {
        pCon->maxTimeout = pConnect->requestTimeout;
    }

    PBRB pBrb;
    PIRP irp;

    status = STATUS_INSUFFICIENT_RESOURCES;
    irp = NULL;
    pBrb = NULL;

    irp = IoAllocateIrp(pCon->pDevice->m_Struct.FunctionalDeviceObject->StackSize,
                        FALSE);

    if (irp != NULL) {
        pBrb = new (NonPagedPool, SDPI_TAG) BRB;

        if (pBrb != NULL) {
            pBrb->BrbHeader.Length = sizeof (_BRB_L2CA_CONNECT_REQ);
            pBrb->BrbHeader.Type = BRB_L2CA_CONNECT_REQ;
            pBrb->BrbHeader.Status = STATUS_SUCCESS;

            pBrb->BrbL2caConnectReq.ContextCxn = (PVOID) pCon;
            pBrb->BrbL2caConnectReq.btAddress = pCon->btAddress;
            pBrb->BrbL2caConnectReq.PSM = PSM_SDP;

            SdpPrint(SDP_DBG_CONFIG_INFO, ("Connect to %04x%08x\n",
                     GET_NAP(pBrb->BrbL2caConnectReq.btAddress),
                     GET_SAP(pBrb->BrbL2caConnectReq.btAddress)));

            IoMarkIrpPending(pIrp);

            pCon->Acquire(pIrp);

            pCon->LockState(&irql);
            pCon->connectList.AddTail(pIrp);
            pCon->UnlockState(irql);

            SdpPrint(SDP_DBG_CONFIG_INFO,
                     ("pending connect request %p\n", irp));

            SendBrbAsync(irp,
                         pBrb,
                         ConnectRequestComplete,
                         pCon,
                         this,
                         pBrb);

            status = STATUS_PENDING;
        }
        else {
            IoFreeIrp(irp);
            irp = NULL;
        }
    }

    return status;
}
#endif // UNDER_CE

 
// !UNDER_CE NTSTATUS SdpInterface::ServiceSearch(PIRP pIrp, ULONG_PTR& info)
NTSTATUS SdpInterface::ServiceSearch(SdpConnection *pCon, SdpServiceSearch *pSearch, BOOL fLocal)
{
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    NTSTATUS status;

	pSearch->cUUIDs = 0;
    status = VerifyServiceSearch(pSearch->uuids, (UCHAR*) &pSearch->cUUIDs);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Check to see if this is a local search
    //
    if (fLocal) {
        ULONG *pResponse;
        USHORT total = 0;

        status = pSdpDB->ServiceSearchRequestResponseLocal(
            pSearch->uuids,
            (UCHAR) pSearch->cUUIDs,
            pSearch->cMaxHandles,
            &pResponse,
            &total);

        if (NT_SUCCESS(status) && pResponse != NULL) {
            ASSERT(total != 0);
			pCon->pClientBuf = (unsigned char*) pResponse;
            pCon->u.Client.ServiceSearch.totalRecordCount = total;
        }
#if defined (DEBUG) || defined (_DEBUG)
        else {
	        ASSERT(pCon->u.Client.ServiceSearch.totalRecordCount == 0);
        }
#endif

        return status;
    }
    return pCon->SendServiceSearchRequest(NULL,pSearch);


#else // UNDER_CE
    SdpConnection *pCon;
    BthSdpServiceSearchRequest *pSearch;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    NTSTATUS status;
    ULONG outlen;
    
    info = 0;

    if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*pSearch)) {
        return STATUS_BUFFER_TOO_SMALL;
    }

    pSearch = (BthSdpServiceSearchRequest *) pIrp->AssociatedIrp.SystemBuffer;

    outlen = stack->Parameters.DeviceIoControl.OutputBufferLength;
    if (outlen == 0 || (outlen % sizeof(ULONG) != 0)) {
        return STATUS_INVALID_BUFFER_SIZE;
    }

    UCHAR maxUuids = 0;

    status = VerifyServiceSearch(pSearch->uuids, &maxUuids);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Check to see if this is a local search
    //
    if (pSearch->hConnection == HANDLE_SDP_LOCAL) {
        ULONG *pResponse;
        USHORT total = 0, maxHandles;

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

        status = Globals.pSdpDB->ServiceSearchRequestResponseLocal(
            pSearch->uuids,
            maxUuids,
            maxHandles,
            &pResponse,
            &total);

        if (NT_SUCCESS(status) && pResponse != NULL) {
            ASSERT(total != 0);

            info = total * sizeof(ULONG);
            RtlCopyMemory((PULONG) pIrp->AssociatedIrp.SystemBuffer, pResponse, info);
            ExFreePool(pResponse);
        }

        return status;
    }

    pCon = NULL;
    status = AcquireConnection(pSearch->hConnection, &pCon, pIrp);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    ASSERT(pCon != NULL);

    //
    // Set the max uuids before we enqueue the request because the send function
    // assumes it is set (even for a queud irp processed at a later time)
    //
    SetMaxUuidsInIrp(pIrp, maxUuids);

    BOOLEAN added = pCon->clientQueue.AddIfBusy(pIrp, &status);

    if (added) {
        //
        // The queue is busy and the request has been queued.  Don't touch the 
        // irp anymore
        //
        return STATUS_PENDING;
    }
    else if (!NT_SUCCESS(status)) {
        //
        // The request was cancelled or something went wrong.  The irp was not 
        // enqueued.  Return the error status
        //
        pCon->ReleaseAndProcessNextRequest(pIrp);
        return status;
    }
    else {
        //
        // This is the current request on the connection, see if it matches the 
        // previous request
        //

        //
        // While we do not cache ServiceSearch responses, this will clean up 
        // any cached responsed from previous queries
        //
        status = pCon->IsPreviousRequest(pIrp,
                                         SdpPDU_ServiceSearchRequest,
                                         pSearch->uuids,
                                         NULL,
                                         0,
                                         &info);

        if (NT_SUCCESS(status) || status == STATUS_BUFFER_TOO_SMALL) {
            pCon->ReleaseAndProcessNextRequest(pIrp);
            return STATUS_SUCCESS;
        }
    }


    return pCon->SendServiceSearchRequest(pIrp);
#endif // UNDER_CE 
}


// NTSTATUS SdpInterface::AttributeSearch(PIRP pIrp, ULONG_PTR& info)
NTSTATUS SdpInterface::AttributeSearch(SdpConnection *pCon, SdpAttributeSearch *pSearch, BOOL fLocal)
{
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    NTSTATUS status; 

    status = 
        VerifyAttributeSearch(pSearch->range,
                              &pSearch->numAttributes,
                              0);

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

    if (fLocal)  {
        PVOID pOrig;
        UCHAR *pResult;

        ULONG size;

        status = pSdpDB->ServiceAttributeRequestResponseLocal(
            pSearch->recordHandle,
            pSearch->range,
            pSearch->numAttributes,
            &pResult,
            &size,
            &pOrig);

        if (NT_SUCCESS(status)) {
            ASSERT(size != 0);
            // pOrig is the base of allocated memory, pResult is what we need to pass
            // to caller, is a few bytes past pOrig.  Rather than have this info propogate up all 
            // the layers just alloc the data here.

            if (NULL == (pCon->pClientBuf = (PUCHAR) SdpAllocatePool(size)))
                 return STATUS_INSUFFICIENT_RESOURCES;
            memcpy(pCon->pClientBuf,pResult,size);         
            pCon->cClientBuf = size;
            SdpFreePool(pOrig);
        }

        return status;
    }
    return pCon->SendAttributeSearchRequest(NULL,pSearch);

#else
    SdpConnection *pCon;
    BthSdpAttributeSearchRequest *pSearch;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    ULONG maxRange;
    NTSTATUS status;

    info = 0;
    maxRange = 0;

    if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*pSearch)) {
        return STATUS_INVALID_BUFFER_SIZE;
    }

    if (stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BthSdpStreamResponse)) {
        return STATUS_INVALID_BUFFER_SIZE;
    }

    pSearch = (BthSdpAttributeSearchRequest *) pIrp->AssociatedIrp.SystemBuffer;

    status =
        VerifyAttributeSearch(pSearch->range,
                              &maxRange,
                              stack->Parameters.DeviceIoControl.InputBufferLength -
                               (sizeof(*pSearch) - sizeof(pSearch->range))
                              );

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

    //
    // Check to see if it is a local search
    //
    if (pSearch->hConnection == HANDLE_SDP_LOCAL) {
        PVOID pOrig;
        UCHAR *pResult;

        ULONG size;

        status = Globals.pSdpDB->ServiceAttributeRequestResponseLocal(
            pSearch->recordHandle,
            pSearch->range,
            maxRange,
            &pResult,
            &size,
            &pOrig);

        if (NT_SUCCESS(status)) {
            //
            // Even if there is no match, you still get an empty sequence
            //
            BthSdpStreamResponse *pResponse = (BthSdpStreamResponse *)
                pIrp->AssociatedIrp.SystemBuffer;

            ULONG responseSize;

            responseSize =
                stack->Parameters.DeviceIoControl.OutputBufferLength -
                (sizeof(*pResponse) - sizeof(pResponse->response));

            pResponse->requiredSize = size;

            if (responseSize < size) {
                info = responseSize;
            }
            else {
                info = size;
            }

            pResponse->responseSize = info;

            RtlCopyMemory(pResponse->response, pResult, info);
            info += (sizeof(*pResponse) - sizeof(pResponse->response));

            ExFreePool(pOrig);
        }

        return status;
    }

    pCon = NULL;
    status = AcquireConnection(pSearch->hConnection, &pCon, pIrp);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    ASSERT(pCon != NULL);

    //
    // Set the max range before we enqueue the request because the send function
    // assumes it is set (even for a queud irp processed at a later time)
    //
    SetMaxRangeInIrp(pIrp, maxRange);

    BOOLEAN added = pCon->clientQueue.AddIfBusy(pIrp, &status);

    if (added) {
        //
        // The queue is busy and the request has been queued.  Don't touch the 
        // irp anymore
        //
        return STATUS_PENDING;
    }
    else if (!NT_SUCCESS(status)) {
        //
        // The request was cancelled or something went wrong.  The irp was not 
        // enqueued.  Return the error status
        //
        pCon->ReleaseAndProcessNextRequest(pIrp);
        return status;
    }
    else {
        //
        // This is the current request on the connection, see if it matches the 
        // previous request
        //

        //
        // While we do not cache ServiceSearch responses, this will clean up 
        // any cached responsed from previous queries
        //
        status = pCon->IsPreviousRequest(pIrp,
                                         SdpPDU_ServiceAttributeRequest,
                                         NULL,
                                         pSearch->range,
                                         maxRange,
                                         &info);

        if (NT_SUCCESS(status) || status == STATUS_BUFFER_TOO_SMALL) {
            pCon->ReleaseAndProcessNextRequest(pIrp);
            return STATUS_SUCCESS;
        }
    }

    return pCon->SendAttributeSearchRequest(pIrp);
#endif // UNDER_CE
}

// NTSTATUS SdpInterface::ServiceAndAttributeSearch(PIRP pIrp, ULONG_PTR& info)
NTSTATUS SdpInterface::ServiceAndAttributeSearch(SdpConnection *pCon, SdpServiceAttributeSearch *pSearch, BOOL fLocal)
{
#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
    NTSTATUS status;

    pSearch->cUUIDs = 0;
    status = VerifyServiceSearch(pSearch->uuids, (UCHAR*) &pSearch->cUUIDs);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    status =
        VerifyAttributeSearch(pSearch->range,
                              &pSearch->numAttributes,
                              0);

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

    if (fLocal) {
        ULONG size;
        UCHAR *pResult;
        
        status = pSdpDB->ServiceSearchAttributeResponseLocal(
            pSearch->uuids,
            (UCHAR) pSearch->cUUIDs,
            pSearch->range,
            pSearch->numAttributes,
            &pResult,
            &size);

        if (NT_SUCCESS(status)) {
            ASSERT(size != 0);

            pCon->pClientBuf = (PUCHAR) pResult;
            pCon->cClientBuf = size;
        }

        return status;
    }
    return pCon->SendServiceSearchAttributeRequest(NULL,pSearch);
#else // UNDER_CE
    SdpConnection *pCon;
    BthSdpServiceAttributeSearchRequest *pSearch;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    NTSTATUS status;
    ULONG maxRange = 0;
    UCHAR maxUuids = 0;

    if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(*pSearch)) {

⌨️ 快捷键说明

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