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

📄 btsdpcon.cpp

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

    PUCHAR pStream = pdu.Write((PUCHAR) u.Client.pRequest);
    pStream += u.Client.rawParametersLength;

    pContState->Write(pStream);

#if DBG
    pStream += pContState->GetTotalSize();
    DbgPrint("%d = %d\n", ((PUCHAR) u.Client.pRequest) - pStream, 
        sizeof(SdpPDU) + pdu.parameterLength);

    ASSERT(((ULONG_PTR) (pStream - ((PUCHAR) u.Client.pRequest))) ==
           sizeof(SdpPDU) + pdu.parameterLength);
#endif 

#if ! ((defined (UNDER_CE) || defined (WINCE_EMULATION)))
    ReadAsync();

    _RegisterConnectionOnTimer(this, SDP_DEFAULT_TIMEOUT);

    Write(u.Client.pRequest, sizeof(SdpPDU) + pdu.parameterLength);

    return STATUS_PENDING;
#else

    int iRet = Write(u.Client.pRequest, sizeof(SdpPDU) + pdu.parameterLength);
    return (iRet==ERROR_SUCCESS) ? STATUS_PENDING : iRet;
#endif
}

NTSTATUS
SdpConnection::OnServiceSearchResponse(
    SdpPDU *pPdu,
    PUCHAR pBuffer,
    ULONG_PTR* pInfo
    )
{
    SDP_ERROR sdpError;

    if (pPdu->transactionId != transactionId-1) {
        //
        // Server error, ergh
        //
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
        *pInfo = pRequestorIrp->IoStatus.Information * sizeof(ULONG);
#endif        
        return STATUS_INVALID_NETWORK_RESPONSE;
    }

    ContinuationState cs;

    USHORT totalCount, currentCount;
    ULONG *pHandleList;
    USHORT handlesSoFar;

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    handlesSoFar = (USHORT) pRequestorIrp->IoStatus.Information;
#else
    handlesSoFar = (USHORT) ConnInformation;
#endif

    NTSTATUS status = SdpInterface::CrackServerServiceSearchResponse(
        pBuffer,
        pPdu->parameterLength,
        &totalCount,
        &currentCount,
        &pHandleList,
        &cs,
        &sdpError
        );

    if (!NT_SUCCESS(status)) {
        //
        // Server is giving back garbage
        //
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
        *pInfo = pRequestorIrp->IoStatus.Information * sizeof(ULONG);
#endif        
        return STATUS_INVALID_NETWORK_RESPONSE;
    }

    if (u.Client.ServiceSearch.totalRecordCount == 0) {
        //
        // First response
        //
        u.Client.ServiceSearch.totalRecordCount = totalCount;  

#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
        cClientBuf = totalCount*sizeof(unsigned long);
        if (cClientBuf) {
            pClientBuf = (unsigned char*) ExAllocatePoolWithTag(0,cClientBuf,0);
            if (!pClientBuf)  {
                return ERROR_OUTOFMEMORY;
            }
        }
#endif // UNDER_CE
    }
    else if (u.Client.ServiceSearch.totalRecordCount != totalCount) {
        //
        // Server is giving back inconsistent results, stop sending requests
        //
        *pInfo = handlesSoFar * sizeof(ULONG);
        return STATUS_INVALID_NETWORK_RESPONSE;
    }
        
    if (handlesSoFar + currentCount > totalCount) {
        //
        // Well, the server gave us too many handles.  
        //
        // TBD:  do we notify the user of this?  if so, how? 
        //
        // just copy over what we can for right now
        //
        currentCount = totalCount - handlesSoFar;
    }

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    PULONG pResult = (PULONG) pRequestorIrp->AssociatedIrp.SystemBuffer;
#else
    PULONG pResult = (PULONG) pClientBuf;
#endif
    for (ULONG i = 0; i < currentCount; i++) {
        ULONG handle;
        
        //
        // pHandleList may not be correctly aligned
        //
        RtlRetrieveUlong(&handle, (pHandleList+i));
        pResult[handlesSoFar + i] = RtlUlongByteSwap(handle);
    }

    handlesSoFar += currentCount;

    if (handlesSoFar == totalCount) {
        //
        // All done
        //
        *pInfo = handlesSoFar * sizeof(ULONG);
        return STATUS_SUCCESS;
    }
    else {
        //
        // Not all done, must ask for more
        //
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
        pRequestorIrp->IoStatus.Information = handlesSoFar;
#else
        ConnInformation = handlesSoFar;
#endif
        return SendContinuationRequestToServer(&cs);
    }
}

NTSTATUS
SdpConnection::OnServiceAttributeResponse(
    SdpPDU *pPdu,
    PUCHAR pBuffer,
    ULONG_PTR* pInfo
    )
{
    SDP_ERROR sdpError;

    if (pPdu->transactionId != transactionId-1) {
        //
        // Server erorr, ergh
        //
        SdpPrint(SDP_DBG_CLIENT_WARNING, ("invalid transaction id!"));
        return STATUS_INVALID_NETWORK_RESPONSE;
    }

    ContinuationState cs;

    UCHAR *pAttribList;
    USHORT listByteCount;

    NTSTATUS status = SdpInterface::CrackServerServiceAttributeResponse(
        pBuffer,
        pPdu->parameterLength,
        &listByteCount,
        &pAttribList,
        &cs,
        &sdpError);

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

#if (defined (UNDER_CE) || defined (WINCE_EMULATION))
	ULONG bytesSoFar;

    ULONG storageSize;
    UCHAR type, sizeIndex;

    bytesSoFar = ConnInformation;

	if (bytesSoFar == 0) {
	    SdpRetrieveHeader(pAttribList, type, sizeIndex);
	    
	    if (type != (UCHAR) SDP_TYPE_SEQUENCE) {
	        return STATUS_INVALID_PARAMETER;
	    }

	    if (sizeIndex < 5 || sizeIndex > 7) {
	        return STATUS_INVALID_PARAMETER; 
	    }
	    SdpRetrieveVariableSize(pAttribList+1,
	                            sizeIndex,
	                            &u.Client.AttributeSearch.responseLength,
	                            &storageSize);	    
		u.Client.AttributeSearch.responseLength += (storageSize + sizeof(UCHAR));
        pClientBuf = (unsigned char*) ExAllocatePoolWithTag(0,u.Client.AttributeSearch.responseLength,0);
        cClientBuf = u.Client.AttributeSearch.responseLength;
        if (!pClientBuf) {
        	return ERROR_OUTOFMEMORY;
        }
    }

    if (bytesSoFar + listByteCount > u.Client.AttributeSearch.responseLength) {
        // server sent us too much data
        return STATUS_INVALID_NETWORK_RESPONSE;
    }
    memcpy(pClientBuf+bytesSoFar,pAttribList,listByteCount);
    ConnInformation += listByteCount;

    if (cs.size == 0) {
        return ERROR_SUCCESS;
    }
    else {
        return SendContinuationRequestToServer(&cs);
    }

#else // UNDER_CE
    BthSdpStreamResponse *pResponse;
    PIO_STACK_LOCATION stack;
    ULONG outLen, responseSize;
    ULONG_PTR bytesSoFar;

    stack = IoGetCurrentIrpStackLocation(pRequestorIrp);
    pResponse =  (BthSdpStreamResponse *) pRequestorIrp->AssociatedIrp.SystemBuffer;

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

    bytesSoFar = pRequestorIrp->IoStatus.Information;

    if (bytesSoFar == 0) {
        //
        // Retrieve the size from first part of the response
        //
        ULONG respTotalSize;
        ULONG storageSize;
        UCHAR type, sizeIndex;

                SdpRetrieveHeader(pAttribList, type, sizeIndex);
    
        if (type != (UCHAR) SDP_TYPE_SEQUENCE) {
            return STATUS_INVALID_PARAMETER;
        }

        if (sizeIndex < 5 || sizeIndex > 7) {
            return STATUS_INVALID_PARAMETER; 
        }

        SdpRetrieveVariableSize(pAttribList+1,
                                sizeIndex,
                                &u.Client.AttributeSearch.responseLength,
                                &storageSize);

        //
        // Take header and the storage space needed for the size into account
        //
        u.Client.AttributeSearch.responseLength += (storageSize + sizeof(UCHAR));

        DbgPrint("----: total response length is %d\n", u.Client.AttributeSearch.responseLength);

        if (u.Client.AttributeSearch.responseLength > responseSize) {
            //
            // We must cache off the request before we start copying the response
            // because they share the same buffer
            //
            SdpAttributeRange *pRange;
            ULONG numRange; 

            if (stack->Parameters.DeviceIoControl.IoControlCode ==
                IOCTL_BTH_SDP_ATTRIBUTE_SEARCH) {

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

                numRange = (stack->Parameters.DeviceIoControl.InputBufferLength -
                                (sizeof(*pSearch) - sizeof(pSearch->range))) /
                            sizeof(SdpAttributeRange);
                pRange = pSearch->range;

                u.Client.lastPduRequest = SdpPDU_ServiceAttributeRequest; 
            }
            else {
                //
                // ServiceSearchAttributeRequest
                //
                BthSdpServiceAttributeSearchRequest *pSearch =
                    (BthSdpServiceAttributeSearchRequest *)
                    pRequestorIrp->AssociatedIrp.SystemBuffer;

                numRange = (stack->Parameters.DeviceIoControl.InputBufferLength -
                                (sizeof(*pSearch) - sizeof(pSearch->range))) /
                            sizeof(SdpAttributeRange);

                pRange = pSearch->range;

                // Save off the uuids as well
                RtlCopyMemory(u.Client.lastUuid,
                              pSearch->uuids,
                              sizeof(u.Client.lastUuid));

                u.Client.lastPduRequest = SdpPDU_ServiceSearchAttributeRequest; 
            }

            u.Client.pLastRange = new(PagedPool, SDPC_TAG) SdpAttributeRange[numRange];

            if (u.Client.pLastRange) {
                u.Client.AttributeSearch.pResponse =
                    new(PagedPool, SDPC_TAG) UCHAR[u.Client.AttributeSearch.responseLength];

                if (u.Client.AttributeSearch.pResponse) {
                    RtlCopyMemory(u.Client.pLastRange,
                                  pRange,
                                  numRange * sizeof(SdpAttributeRange));
                    u.Client.numRange = numRange;
                }
                else {
                    return STATUS_INSUFFICIENT_RESOURCES;
                }
            }
            else {
                return STATUS_INSUFFICIENT_RESOURCES;
            }
        }
    }

    DbgPrint("----: bytes so far (%d), current PDU (%d)\n",  bytesSoFar, listByteCount);

    if (bytesSoFar + listByteCount > u.Client.AttributeSearch.responseLength) {
        //
        // server sent us too much data
        //
        return STATUS_INVALID_NETWORK_RESPONSE;
    }

    if (u.Client.AttributeSearch.pResponse) {
        // copy to cache
        RtlCopyMemory(u.Client.AttributeSearch.pResponse + bytesSoFar,
                      pAttribList,
                      listByteCount);
    }
    else {
        // copy to requestor buffer
        RtlCopyMemory(pResponse->response + bytesSoFar,
                      pAttribList,
                      listByteCount);
    }

    pRequestorIrp->IoStatus.Information = bytesSoFar + listByteCount;

    if (cs.size == 0) {
        DbgPrint("----: we are done!\n");

        //
        // We are done, give the user his response back
        //
        ASSERT(pRequestorIrp->IoStatus.Information == 
               u.Client.AttributeSearch.responseLength);

        //
        // Everything but the response buffer for now
        //
        *pInfo = sizeof(*pResponse) - sizeof(pResponse->response);

        if (u.Client.AttributeSearch.pResponse) {
            DbgPrint("----:  not enough client space to fill in, caching\n");

            //
            // Not enough room in the user buffer to give the entire response
            // back, so copy as much as possible
            //
            RtlCopyMemory(pResponse->response,
                          u.Client.AttributeSearch.pResponse,
                          responseSize);

            pResponse->responseSize = responseSize; 

            pResponse->requiredSize = u.Client.AttributeSearch.responseLength;
            status = STATUS_BUFFER_TOO_SMALL;
        }
        else {
            DbgPrint("----:  enough room!!!\n");

            //
            // There is enough room for all
            //
            pResponse->requiredSize = (ULONG) pRequestorIrp->IoStatus.Information;
            pResponse->responseSize = pResponse->requiredSize;  

            status = STATUS_SUCCESS;
        }

        *pInfo += pResponse->responseSize;

        return status;
    }
    else {
        DbgPrint("----: get more from the server!\n");

        //
        // get more info from the server
        //
        return SendContinuationRequestToServer(&cs);
    }
#endif // UNDER_CE
}

NTSTATUS
SdpConnection::OnServiceSearchAttributeResponse(
    SdpPDU *pPdu,
    PUCHAR pBuffer,
    ULONG_PTR* pInfo
    )
{
    return OnServiceAttributeResponse(pPdu, pBuffer, pInfo);
}

BOOLEAN
SdpConnection::IsRequestContinuation(
    SdpPDU *pPdu,
    PUCHAR pRequest, 
    ContinuationState *pConStateReq,
    BOOLEAN &cleanUpRequired,
    BOOLEAN &contError
    )
{
    contError = FALSE;

    if (u.Server.pClientRequest == NULL) {
        cleanUpRequired = FALSE;
        if (pConStateReq->size != 0) {
            contError = TRUE;
        }
        return FALSE;
    }

    cleanUpRequired = TRUE;

    if (pPdu->pduId != u.Server.lastPduRequest) {
        return FALSE;
    }

    ContinuationState cs(this);

    ULONG

⌨️ 快捷键说明

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