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

📄 btsdp.cpp

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


    //
    // max attrib byte count = 2
    // attrib elem seq       = 5 (see above)
    // cont state            = 1
    //                       = 8
    //
    *ppServiceSearchSequence = pStream;
    status =
        CrackSequenceParameter(pStream, streamSize, 8, pServiceSearchSequenceSize);
                                    
    if (!NT_SUCCESS(status)) {
        *pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    RtlRetrieveUshort(pMaxAttributeByteCount, pStream);
    *pMaxAttributeByteCount = RtlUshortByteSwap(*pMaxAttributeByteCount);

    pStream += sizeof(USHORT);
    streamSize -= sizeof(USHORT);

    //
    // cont state = 1
    //
    *ppAttributeIdSequence = pStream;
    status =
        CrackSequenceParameter(pStream, streamSize, 1, pAttributeIdSequenceSize);

    if (!NT_SUCCESS(status)) {
        *pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    return CrackContState(pStream, streamSize, pContState, pSdpError);
}

NTSTATUS
SdpInterface::CrackServerServiceSearchResponse(
    IN UCHAR *pResponseStream,
    IN ULONG streamSize,
    OUT USHORT *pTotalCount,
    OUT USHORT *pCurrentCount,
    OUT ULONG **ppHandleList,
    OUT ContinuationState *pContState,
    OUT PSDP_ERROR pSdpError
    )
{
    //
    // sizeof(total count)      = 2
    // sizeof(current count)    = 2
    // sizeof(0+ handles)       = 0
    // sizeof(cont state)      >= 1
    //
    if (streamSize < 5) {
        *pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    USHORT tmp;

    RtlRetrieveUshort(&tmp, pResponseStream);
    *pTotalCount = RtlUshortByteSwap(tmp);
    pResponseStream += sizeof(tmp);
    streamSize -= sizeof(tmp);

    RtlRetrieveUshort(&tmp, pResponseStream);
    *pCurrentCount = RtlUshortByteSwap(tmp);
    pResponseStream += sizeof(tmp);
    streamSize -= sizeof(tmp);

    //
    // see if the described number of records plus a finishing cont state is 
    // greater than what was sent OR if the current count is greater than the 
    // reported max count (incositent results)
    // 
    if ((*pCurrentCount * sizeof(ULONG) + 1 > streamSize) ||
        (*pCurrentCount > *pTotalCount)) {
        *pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    *ppHandleList = (ULONG *) pResponseStream;
    pResponseStream += sizeof(ULONG) * (*pCurrentCount);
    streamSize -= sizeof(ULONG) * (*pCurrentCount); 

    return CrackContState(pResponseStream, streamSize, pContState, pSdpError);
}

NTSTATUS 
SdpInterface::CrackServerServiceAttributeResponse(
    IN UCHAR *pResponseStream,
    IN ULONG streamSize,
    OUT USHORT *pByteCount,
    OUT UCHAR **ppAttributeList,
    OUT ContinuationState *pContState,
    OUT PSDP_ERROR pSdpError
    )
{
    //
    // sizeof(list byte count)      = 2
    // sizeof(+1 byte attrib list)  = 1
    // sizeof(cont state)          >= 1
    //
    if (streamSize < 4) {
        *pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    USHORT tmp;

    RtlRetrieveUshort(&tmp, pResponseStream);
    *pByteCount = RtlUshortByteSwap(tmp);
    pResponseStream += sizeof(tmp);
    streamSize -= sizeof(tmp);

    *ppAttributeList = (UCHAR *) pResponseStream;

    ULONG count = *pByteCount;

    if (count + 1 > streamSize) {
        *pSdpError = MapNtStatusToSdpError(STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

    pResponseStream += count;
    streamSize -= count;

    return CrackContState(pResponseStream, streamSize, pContState, pSdpError);
}

NTSTATUS
SdpInterface::CreateServiceAttributePDU(
    IN UCHAR *pResult,
    IN ULONG resultSize,
    IN ContinuationState *pContState,
    IN USHORT maxAttribByteCount,   
    IN ULONG mtu,
    OUT UCHAR **ppResponse,
    OUT ULONG *pResponseSize,
    OUT UCHAR **ppNextResult,
    OUT ULONG *pNextResultSize,
    OUT PSDP_ERROR pSdpError
    )
{
    NTSTATUS status;
    ULONG fixedSize, adjustedResponseSize = 0;
    USHORT byteCount = 0;
    UCHAR *pStream;

    //
    // PDU header + byte count + cont state header
    //
    fixedSize = sizeof(SdpPDU) + sizeof(byteCount) + sizeof(UCHAR);

    SdpPrint(SDP_DBG_PDU_TRACE, ("CreateServiceAttributePDU called\n"));

    SdpPrint(SDP_DBG_PDU_INFO, ("fixed %d,  result %d, mtu %d\n",
             fixedSize, resultSize, mtu));

    if (fixedSize + resultSize <= mtu) {
        //
        // We can fit the entire response in a single PDU...let's see if 
        // maxAttribByteCount allows us to do this
        //
        if (resultSize > maxAttribByteCount) {
            //
            // compute whatever amount of space is leftover
            //
            adjustedResponseSize = mtu - (fixedSize + pContState->size);

            SdpPrint(SDP_DBG_PDU_INFO,
                     ("could fit, res size > mtu, adjusted size %d\n",
                     adjustedResponseSize));

            //
            // still too big, just go smaller
            //
            if (adjustedResponseSize > maxAttribByteCount) {
                SdpPrint(SDP_DBG_PDU_INFO,
                         ("adjusted size (%d) bigger than max byte count (%d), fixing\n",
                         adjustedResponseSize, maxAttribByteCount));

                adjustedResponseSize = maxAttribByteCount;
            }
        }
        else {
            //
            // everything fits, set the cont state to reflect this
            //
            SdpPrint(SDP_DBG_PDU_INFO, ("everything fits\n"));
            pContState->size = 0;
        }
    }
    else {
        //
        // the entire response doesn't fit into the mtu, must trim it down
        //
        adjustedResponseSize = mtu - (fixedSize + pContState->size);

        SdpPrint(SDP_DBG_PDU_INFO,
                 ("total bigger than mtu, adjusted size %d\n",
                  adjustedResponseSize));

        if (adjustedResponseSize > maxAttribByteCount) {
            SdpPrint(SDP_DBG_PDU_INFO,
                     ("still too big, setting to max attrib byte count %d\n",
                     adjustedResponseSize));

            adjustedResponseSize = maxAttribByteCount;
        }
    }
                                   
    if (adjustedResponseSize > 0) {
        SdpPrint(SDP_DBG_PDU_INFO,
                 ("adjustedResponseSize is %d\n", (ULONG) adjustedResponseSize));

        ASSERT(pContState->size != 0);

        *ppNextResult = pResult + adjustedResponseSize;
        *pNextResultSize = resultSize - adjustedResponseSize;
        resultSize = adjustedResponseSize;

        SdpPrint(SDP_DBG_PDU_INFO,
                 ("remaining result size %d\n", *pNextResultSize));
    }
    else {
        SdpPrint(SDP_DBG_PDU_INFO, ("done...zeroing out continuation stuff\n"));

        *ppNextResult = NULL;
        *pNextResultSize = 0;
    }

    *pResponseSize = fixedSize + resultSize + pContState->size;
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    *ppResponse =  new (PagedPool, SDPI_TAG) UCHAR[*pResponseSize];
#else
	if (NULL != (*ppResponse = (PUCHAR) ExAllocatePoolWithTag(0,sizeof(UCHAR)*(*pResponseSize),0)))
	    memset(*ppResponse,0,*pResponseSize);
#endif
    if (*ppResponse == NULL) {
        SdpPrint(SDP_DBG_PDU_ERROR,
                 ("could not allocate stream response for response\n"));

        status = STATUS_INSUFFICIENT_RESOURCES;
        *pSdpError = MapNtStatusToSdpError(status);

        return status;
    }

    //
    // Write out the response except for the PDU
    //
    pStream  = *ppResponse;
    pStream += sizeof(SdpPDU);

    ASSERT(resultSize <= 0xFFFF);

    //
    // Easy, just one (or the last) PDU
    //
    byteCount = (USHORT) resultSize;
    byteCount = RtlUshortByteSwap(byteCount);

    RtlCopyMemory(pStream, &byteCount, sizeof(byteCount));
    pStream += sizeof(byteCount);

    RtlCopyMemory(pStream, pResult, resultSize);
    pStream += resultSize;

    pContState->Write(pStream);

    //
    // Make sure we wrote out all the byte we thought we did
    //
#if DBG
    pStream += pContState->GetTotalSize();
    ASSERT(((ULONG) (pStream  - *ppResponse)) == *pResponseSize);
#endif

    return STATUS_SUCCESS;
}

NTSTATUS
SdpInterface::CreateServiceSearchAttributePDU(
    IN UCHAR *pResult,
    IN ULONG resultSize,
    IN ContinuationState *pContState,
    IN USHORT maxAttribByteCount,
    IN USHORT mtu,
    OUT UCHAR **ppResponse,
    OUT ULONG *pResponseSize,
    OUT UCHAR **ppNextResult,
    OUT ULONG *pNextResultSize,
    OUT PSDP_ERROR pSdpError
    )
{
    return CreateServiceAttributePDU(pResult,
                                     resultSize,
                                     pContState,
                                     maxAttribByteCount,
                                     mtu,
                                     ppResponse,
                                     pResponseSize,
                                     ppNextResult,
                                     pNextResultSize,
                                     pSdpError);
}

NTSTATUS
SdpInterface::CreateServiceSearchResponsePDU(
    ULONG *pRecordHandles,
    USHORT recordCount,
    USHORT totalRecordCount,
    IN ContinuationState *pContState,
    IN USHORT mtu,
    OUT UCHAR **ppResponse,
    OUT ULONG *pResponseSize,
    OUT ULONG **ppNextRecordHandles,
    OUT USHORT *pNextRecordCount,
    OUT PSDP_ERROR pSdpError
    )
{
    NTSTATUS status;
    ULONG fixedSize;
    USHORT count;

    fixedSize = 
           sizeof(SdpPDU)      +
           sizeof(USHORT)      +    // TotalServiceRecordCount
           sizeof(USHORT)      +    // CurrentServiceRecordCount
           sizeof(UCHAR);           // continuation state of 0

    *ppNextRecordHandles = NULL; 
    *pNextRecordCount = 0; 
     
    SdpPrint(SDP_DBG_PDU_TRACE, ("CreateServiceSearchResponsePDU called\n"));

    SdpPrint(SDP_DBG_PDU_TRACE, ("mtu is %d, response size is %d\n",
             (ULONG) mtu, fixedSize + (recordCount * sizeof(ULONG)))); 

    if (fixedSize + (recordCount * sizeof(ULONG)) > ((ULONG) mtu)) {
        //
        // figure out how much space we have left for the record handles
        //
        count = (mtu - ((USHORT) (fixedSize + pContState->size))) / sizeof(ULONG);
        if (count == 0) {
            SdpPrint(SDP_DBG_PDU_WARNING,
                     ("could not fit in a single handle!!!!\n"));

            //
            // can't fit any record handles, ergh!
            //
            return STATUS_INVALID_BUFFER_SIZE;
        }

        ASSERT(recordCount > count);

        //
        // total required size
        //
        *ppNextRecordHandles = pRecordHandles + count;
        *pNextRecordCount = recordCount - count;

        recordCount = count;
    }
    else {
        pContState->size = 0;
    }

    *pResponseSize = fixedSize + recordCount * sizeof(ULONG) + pContState->size;

    SdpPrint(SDP_DBG_PDU_INFO,
             ("returning %d records (%d total), resp sizse is %d\n",
              recordCount, totalRecordCount, *pResponseSize));

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    *ppResponse = new(PagedPool, SDPI_TAG) UCHAR[*pResponseSize];
#else
    if (NULL != (*ppResponse = (PUCHAR) ExAllocatePoolWithTag(0,*pResponseSize,0)))
        memset(*ppResponse,0,*pResponseSize);
#endif

    if (*ppResponse == NULL) {
        SdpPrint(SDP_DBG_PDU_ERROR,
                 ("could not allocate a stream for a response\n"));

        status = STATUS_INSUFFICIENT_RESOURCES; 
        *pSdpError = MapNtStatusToSdpError(status);
        return status;
    }

    //
    // Write out the response except for the PDU.  Format is
    //
    //  total record count            (2 bytes)
    //  record count in this response (2 bytes)
    //  handles                       (record count * sizeof(ULONG))
    //  continuation state            (1-17 bytes)
    //
    UCHAR *pStream = *ppResponse + sizeof(SdpPDU);

    totalRecordCount = RtlUshortByteSwap(totalRecordCount);
    RtlCopyMemory(pStream, &totalRecordCount, sizeof(totalRecordCount));
    pStream += sizeof(totalRecordCount);

    count = RtlUshortByteSwap(recordCount);
    RtlCopyMemory(pStream, &count, sizeof(count));
    pStream += sizeof(count);

    if (recordCount) {
        RtlCopyMemory(pStream, pRecordHandles, recordCount * sizeof(ULONG));
        pStream +=(recordCount * sizeof(ULONG));
    }

    //
    //  Finally the cont state
    //
    pContState->Write(pStream);

    //
    // Make sure we wrote only the number bytes we said we did
    //
#if DBG
    pStream += pContState->GetTotalSize();
    ASSERT(((ULONG) (pStream - *ppResponse)) == *pResponseSize);
#endif

    return STATUS_SUCCESS;
}


#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

NTSTATUS
SdpInterface::ConnectRequestComplete(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
    )
{
    PIO_STACK_LOCATION stack;
    SdpInterface *pSdpInterface;
    SdpConnection *pCon;
    PBRB pBrb;

    stack = IoGetCurrentIrpStackLocation(Irp);
    pSdpInterface = (SdpInterface *) stack->Parameters.Others.Argument1;
    pBrb = (BRB *) stack->Parameters.Others.Argument2;

    pCon = (SdpConnection *) Context;

    SdpPrint(SDP_DBG_CONFIG_TRACE,
             ("+ConnectRequestComplete: status 0x%x, hCon %p, con %p\n",
              Irp->IoStatus.Status, pBrb->BrbL2caConnectReq.hConnection, pCon));

    if (NT_SUCCESS(Irp->IoStatus.Status)) {
        //
        // Assigned when enter the config state

⌨️ 快捷键说明

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