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

📄 verify.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "pch.h"
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
#include "bt_100.h"

#pragma code_seg("PAGE", "CODE")
#endif

UCHAR IdxToSize[] = {
    sizeof(UCHAR),
    sizeof(USHORT),
    sizeof(ULONG),
    sizeof(ULONGLONG),
    sizeof(ULONGLONG) * 2
};

#define INC_STREAM(_inc)        \
{                               \
    pStream += (_inc);           \
    size -= (_inc);             \
}

NTSTATUS
SdpVerifySequenceOf(
    UCHAR *pStream,
    ULONG size,
    UCHAR ofType,
    UCHAR *pSpecSizes,
    ULONG *pNumFound,
    PSDP_STREAM_WALK_FUNC pFunc,
    PVOID pContext
    )
{

    UCHAR type, sizeIndex;

    SdpRetrieveHeader(pStream, type, sizeIndex);

    if (type != SDP_TYPE_SEQUENCE) {
        return STATUS_INVALID_PARAMETER;
    }

    INC_STREAM(1);

    ULONG elementSize, storageSize;
    SdpRetrieveVariableSize(pStream, sizeIndex, &elementSize, &storageSize);

    INC_STREAM(storageSize);
    
    //
    // Make sure the top level seqeunce is the only element in the stream
    //
    if (size != elementSize) {
        return STATUS_INVALID_PARAMETER;
    }

    while (size) {
        SdpRetrieveHeader(pStream, type, sizeIndex);

        if (type != ofType) {
            return STATUS_INVALID_PARAMETER;
        }         

        INC_STREAM(1);

        if (pSpecSizes) {
            BOOLEAN matched = FALSE;

            for (ULONG idx = 0; pSpecSizes[idx] != 0x00; idx++) {
                if (IdxToSize[sizeIndex] == pSpecSizes[idx]) {
                    matched = TRUE;
                    break;
                }
            }

            if (matched == FALSE) {
                return STATUS_INVALID_PARAMETER;
            }
        }

        if (ARGUMENT_PRESENT(pNumFound)) {
            (*pNumFound)++;
        }

        ULONG dataSize;
        switch (sizeIndex) {
        case 0: 
        case 1: 
        case 2: 
        case 3:
        case 4:
            dataSize = IdxToSize[sizeIndex];
            break;

        default:
            SdpRetrieveVariableSize(pStream, sizeIndex, &dataSize, &storageSize);
            INC_STREAM(storageSize);
            break;
        }

        if (pFunc != NULL) {
            NTSTATUS status = pFunc(pContext,
                                    type,
                                    dataSize,
                                    pStream,
                                    0);

            if (!NT_SUCCESS(status) && status != STATUS_REPARSE_POINT_NOT_RESOLVED) {
                return status;
            }
        }

        INC_STREAM(dataSize);
    }
    
    return STATUS_SUCCESS;
}

typedef NTSTATUS (*PFNVERIFY)(PUCHAR pStream, ULONG size, ULONG flags);

struct ProtocolListInfo {
    ProtocolListInfo(ULONG f) : firstSequence(TRUE), havePsm(FALSE), psmFromUuid(FALSE), flags(f) {}

    ULONG flags;
    BOOLEAN firstSequence;
    BOOLEAN psmFromUuid;
    BOOLEAN havePsm;
};

NTSTATUS
WalkProtocolSequence(
    ProtocolListInfo *pInfo, 
    UCHAR DataType, 
    ULONG DataSize,
    PUCHAR Data,
    ULONG DataStorageSize
    )
{
    UCHAR type, sizeIndex;

    //
    // must have content
    //
    if (DataSize == 0) {
        return STATUS_INVALID_PARAMETER;
    }

    SdpRetrieveHeader(Data, type, sizeIndex);

    //
    // first element must be a UUID
    //
    if (type != SDP_TYPE_UUID) {
        return STATUS_INVALID_PARAMETER;
    }

    Data += 1;
    DataSize -= 1;

    GUID uuid;
    SdpRetrieveUuidFromStream(Data, IdxToSize[sizeIndex], &uuid, FALSE);

    DataSize -= IdxToSize[sizeIndex];

    //
    // Perform this check for local services only b/c who knows what is on
    // the remote device.
    //
    if (pInfo->flags & VERIFY_CHECK_MANDATORY_LOCAL) {
        if (pInfo->firstSequence) {
            //
            // ISSUE:  right now every profile specifies L2CAP as the lowest layer
            //         which means that if any profile comes along that doesn't specify
            //         L2CAP, this needs to be changed....but I don't see that 
            //         happening anytime soon and all we implement is l2cap anyways
            if (!IsEqualUuid(&uuid, &L2CAP_PROTOCOL_UUID)) {
                //
                // first protocol must L2CAP
                //
                return STATUS_INVALID_PARAMETER;
            }
    
            //
            // no PSM in the record, see if we can determine it from a well known
            // protocol on top of L2CAP
            //
            if (DataSize == 0) {
                pInfo->psmFromUuid = TRUE;
            }

            pInfo->firstSequence = FALSE;
        }
        else if (pInfo->psmFromUuid && pInfo->havePsm == FALSE) {
            if (IsEqualUuid(&uuid, &SDP_PROTOCOL_UUID)     ||
                IsEqualUuid(&uuid, &RFCOMM_PROTOCOL_UUID)  ||
                IsEqualUuid(&uuid, &TCSBIN_PROTOCOL_UUID)) {
                pInfo->havePsm = TRUE;
            }
            else {
                return STATUS_INVALID_PARAMETER;
            }
        }
    }

    //
    // We only know how to look at L2CAP and RFCOMM optinal elements
    //
    if (DataSize) {
        Data += IdxToSize[sizeIndex];

        SdpRetrieveHeader(Data, type, sizeIndex);

        if (IsEqualUuid(&uuid, &L2CAP_PROTOCOL_UUID)) {
            //
            // PSM
            //
            if (type != SDP_TYPE_UINT || IdxToSize[sizeIndex] != sizeof(USHORT)) {
                return STATUS_INVALID_PARAMETER;
            }
            pInfo->havePsm = TRUE;
            ASSERT(pInfo->psmFromUuid == FALSE);
        }
        else if (IsEqualUuid(&uuid, &RFCOMM_PROTOCOL_UUID)) {
            //
            // Channel number
            //
            if (type != SDP_TYPE_UINT || IdxToSize[sizeIndex] != sizeof(UCHAR)) {
                return STATUS_INVALID_PARAMETER;
            }
        }
    }

    return STATUS_SUCCESS;
}

NTSTATUS VerifyProtocolList(PUCHAR pStream, ULONG size, ULONG flags)
{
    UCHAR type, sizeIndex;
    ULONG numFound;
    NTSTATUS status;

    SdpRetrieveHeader(pStream, type, sizeIndex);

    if (type == SDP_TYPE_SEQUENCE) {
        ProtocolListInfo pli(flags);

        numFound = 0;
        status = SdpVerifySequenceOf(pStream,
                                     size,
                                     SDP_TYPE_SEQUENCE,
                                     NULL,
                                     &numFound,
                                     (PSDP_STREAM_WALK_FUNC) WalkProtocolSequence,
                                     &pli);
        if (NT_SUCCESS(status) &&
            (numFound == 0 ||
             (pli.havePsm == FALSE && (flags & VERIFY_CHECK_MANDATORY_LOCAL)))) {
            return STATUS_INVALID_PARAMETER;
        }
        
        return status;
    }
    else if (type == SDP_TYPE_ALTERNATIVE) {
        //
        // iterate over the list, making sure each one is a well formed sequence
        // of sequences
        //
        ULONG elementSize, storageSize;
    
        INC_STREAM(1);
        SdpRetrieveVariableSize(pStream, sizeIndex, &elementSize, &storageSize);
    
        //
        // must have content
        //
        if (elementSize == 0) {
            return STATUS_INVALID_PARAMETER;
        }

        INC_STREAM(storageSize);

        //
        // must be the only element in the stream
        //
        if (size != elementSize) {
            return STATUS_INVALID_PARAMETER;
        }

        while (size) {
            SdpRetrieveHeader(pStream, type, sizeIndex);

            if (type != SDP_TYPE_SEQUENCE) {
                return STATUS_INVALID_PARAMETER;
            }

            PUCHAR tmpStream = pStream;

            INC_STREAM(1);

            SdpRetrieveVariableSize(pStream, sizeIndex, &elementSize, &storageSize);

            ProtocolListInfo pli(flags);

            numFound = 0;
            status =
                SdpVerifySequenceOf(tmpStream,
                                    elementSize + storageSize + 1, // 1 == elem header
                                    SDP_TYPE_SEQUENCE,
                                    NULL,
                                    &numFound,
                                    (PSDP_STREAM_WALK_FUNC) WalkProtocolSequence,
                                    &pli);

            if (!NT_SUCCESS(status)) {
                return status;
            }
            else if (numFound == 0 ||
                     (pli.havePsm == FALSE && (flags & VERIFY_CHECK_MANDATORY_LOCAL))) {
                return STATUS_INVALID_PARAMETER;
            }

            INC_STREAM(storageSize);
            INC_STREAM(elementSize);
        }

        return STATUS_SUCCESS;
    }
    else {
        return STATUS_INVALID_PARAMETER;
    }
}

NTSTATUS VerifyLangIdList(PUCHAR pStream, ULONG size, ULONG flags)
{
    UCHAR sizes[] = { sizeof(USHORT), 0x00 };
    ULONG numFound = 0;
    NTSTATUS status;

    status = SdpVerifySequenceOf(pStream,
                                 size,
                                 SDP_TYPE_UINT, 
                                 sizes,
                                 &numFound,
                                 NULL,
                                 NULL);

    if (NT_SUCCESS(status) && ( (numFound == 0) || (numFound % 3 != 0) ) ) {
        status = STATUS_INVALID_PARAMETER; 
    }

    return status;
}

NTSTATUS
WalkProfileDescriptor(
    PVOID pContext,
    UCHAR DataType, 
    ULONG DataSize,
    PUCHAR Data,
    ULONG DataStorageSize
    )
{
    UCHAR type, sizeIndex;

    //
    // must have content
    //
    if (DataSize == 0) {
        return STATUS_INVALID_PARAMETER;
    }

    SdpRetrieveHeader(Data, type, sizeIndex);

    Data += 1;

⌨️ 快捷键说明

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