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

📄 verify.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    DataSize -= 1;

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

    Data += IdxToSize[sizeIndex];
    DataSize -= IdxToSize[sizeIndex];

    if (DataSize == 0) {
        return STATUS_INVALID_PARAMETER;
    }

    SdpRetrieveHeader(Data, type, sizeIndex);
    
    Data += 1;
    DataSize -= 1;

    if (type != SDP_TYPE_UINT ||
        IdxToSize[sizeIndex] != sizeof(USHORT) ) {
        return STATUS_INVALID_PARAMETER;
    }

    Data += sizeof(USHORT);
    DataSize -= sizeof(USHORT);

    if (DataSize != 0) {
        return STATUS_INVALID_PARAMETER;
    }

    return STATUS_SUCCESS;
}

NTSTATUS VerifyProfileDescriptor(PUCHAR pStream, ULONG size, ULONG flags)
{
    NTSTATUS status;
    ULONG numFound = 0;

    status = SdpVerifySequenceOf(pStream,
                                 size,
                                 SDP_TYPE_SEQUENCE,
                                 NULL,
                                 &numFound,
                                 WalkProfileDescriptor,
                                 NULL);

    if (NT_SUCCESS(status) && numFound == 0) {
        return STATUS_INVALID_PARAMETER;
    }

    return status;
}

#define VADF_REQ_LOCAL   0x01
#define VADF_REQ_REMOTE  0x02
#define VADF_SEQ         0x10

#define VADF_REQ_ALL     (VADF_REQ_LOCAL | VADF_REQ_REMOTE)

struct VerifyAttibuteData {
    USHORT attribute;
    USHORT flags;
    UCHAR  attributeType;
    UCHAR *pAttributeSizes;

    //
    // has precedence over any flags
    //
    PFNVERIFY pfnVerify;    
};

UCHAR HandleSizes[] =      { sizeof(ULONG),  0x00 };
UCHAR RecordStateSizes[] = { sizeof(ULONG),  0x00 };
UCHAR LangIdSizes[] =      { sizeof(USHORT), 0x00 };
UCHAR TimeToLiveSizes[] =  { sizeof(ULONG),  0x00 };
UCHAR AvailabilitySizes[] ={ sizeof(UCHAR),  0x00 };

VerifyAttibuteData VerData[] = {
#if 0
    { SDP_ATTRIB_RECORD_HANDLE,    VADF_REQ_ALL,                    SDP_TYPE_UINT, HandleSizes, NULL},
#else
    { SDP_ATTRIB_RECORD_HANDLE,    VADF_REQ_REMOTE,                 SDP_TYPE_UINT, HandleSizes, NULL},
#endif
    { SDP_ATTRIB_CLASS_ID_LIST,    VADF_REQ_ALL | VADF_SEQ,         SDP_TYPE_UUID, NULL, NULL},
    { SDP_ATTRIB_RECORD_STATE,             0x00,                    SDP_TYPE_UINT, RecordStateSizes, NULL},
    { SDP_ATTRIB_SERVICE_ID,               0x00,                    SDP_TYPE_UUID, NULL, NULL},
#if 0
    { SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST, VADF_REQ_LOCAL,          0x00,          NULL, VerifyProtocolList},
#else
    { SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST, 0x00,                    0x00,          NULL, VerifyProtocolList},
#endif
    { SDP_ATTRIB_BROWSE_GROUP_LIST,        VADF_SEQ,                SDP_TYPE_UUID, NULL, NULL},
    { SDP_ATTRIB_LANG_BASE_ATTRIB_ID_LIST, 0x00,                    SDP_TYPE_UINT, LangIdSizes, VerifyLangIdList},
    { SDP_ATTRIB_INFO_TIME_TO_LIVE,        0x00,                    SDP_TYPE_UINT, TimeToLiveSizes, NULL},
    { SDP_ATTRIB_AVAILABILITY,             0x00,                    SDP_TYPE_UINT, AvailabilitySizes, NULL},
    { SDP_ATTRIB_PROFILE_DESCRIPTOR_LIST,  0x00,                    0x00,          NULL, VerifyProfileDescriptor},
    { SDP_ATTRIB_DOCUMENTATION_URL,        0x00,                    SDP_TYPE_URL,  NULL, NULL},
    { SDP_ATTRIB_CLIENT_EXECUTABLE_URL,    0x00,                    SDP_TYPE_URL,  NULL, NULL},
    { SDP_ATTRIB_ICON_URL,                 0x00,                    SDP_TYPE_URL,  NULL, NULL},
};

ULONG VerDataMax = sizeof(VerData) / sizeof(VerData[0]);

NTSTATUS
SdpVerifyServiceRecord(
    UCHAR *pStream,
    ULONG size,
    ULONG flags,
    USHORT *pAttribId
    )
{
    NTSTATUS status = STATUS_NOT_FOUND;
    ULONG attributeStreamSize;
//  USHORT particularAttribute;
    UCHAR *pAttributeStream;
    
    //
    // If the stream is the attribute value itself, then make sure the single
    // attribute flag is set as well
    //
    if ((flags & VERIFY_STREAM_IS_ATTRIBUTE_VALUE)) {
        flags |= VERIFY_SINGLE_ATTRIBUTE;
    }

    for (ULONG idx = 0; idx < VerDataMax; idx++) {
        if ((flags & VERIFY_SINGLE_ATTRIBUTE) &&
            *pAttribId != VerData[idx].attribute) {
            continue;
        }

        if (flags & VERIFY_STREAM_IS_ATTRIBUTE_VALUE) {
            status = STATUS_SUCCESS;
            pAttributeStream = pStream;
            attributeStreamSize = size;
        }
        else {
            status = SdpFindAttributeInStream(pStream,
                                              size,
                                              VerData[idx].attribute,
                                              &pAttributeStream,
                                              &attributeStreamSize);
        }

        //
        // See if we have successfully found a stream which the attribute value
        //
        if (NT_SUCCESS(status)) {
            if (VerData[idx].pfnVerify != NULL) {
                //
                // Custom verifier, just call it and let it handle everything
                //
                status = VerData[idx].pfnVerify(pAttributeStream,
                                                attributeStreamSize,
                                                flags);
            }
            else if (VerData[idx].flags & VADF_SEQ) {
                ULONG numFound = 0;

                //
                // It is a sequence which is homogeneous.  It is assumed that
                // the sequence cannot be empty.
                //
                status = SdpVerifySequenceOf(pAttributeStream,
                                             attributeStreamSize,
                                             VerData[idx].attributeType,
                                             VerData[idx].pAttributeSizes,
                                             &numFound,
                                             NULL,
                                             NULL);

                if (NT_SUCCESS(status) && numFound == 0) {
                    status = STATUS_INVALID_PARAMETER;
                }
            }
            else {
                //
                // Singular type with 0 - N possible specific sizes
                //
                UCHAR type, sizeIndex;

                SdpRetrieveHeader(pAttributeStream, type, sizeIndex);

                if (type != VerData[idx].attributeType) {
                    status = STATUS_INVALID_PARAMETER;
                }
                else if (VerData[idx].pAttributeSizes) {
                    BOOLEAN matched = FALSE;

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

                    if (matched == FALSE) {
                        status = STATUS_INVALID_PARAMETER;
                    }
                }
                else {
                    // All sizes are valid
                    ;
                }
            }
        }
        else if (  (flags & VERIFY_SINGLE_ATTRIBUTE)            ||
                  ((flags & VERIFY_CHECK_MANDATORY_LOCAL)  &&
                   (VerData[idx].flags & VADF_REQ_LOCAL))       || 
                  ((flags & VERIFY_CHECK_MANDATORY_REMOTE) &&
                   (VerData[idx].flags & VADF_REQ_REMOTE)) ) {
            //
            // One of these have, and the attribute was not present 
            // 1  Caller has asked to verify one attribute 
            // 2  Caller wants all mandatory local attributes verified
            // 3  Caller wants all remote local attributes verified
            //
            status = STATUS_NOT_FOUND;
        }
        else {
            //
            // The attribute was not found, but it is not required, so just 
            // consider it a success
            //
            status = STATUS_SUCCESS;
        }

        //
        // Break out of the loop if the check failed or if we are only verifying
        // one attribute
        //
        if (!NT_SUCCESS(status) || (flags & VERIFY_SINGLE_ATTRIBUTE)) {
            break;
        }
    }

    if (!NT_SUCCESS(status) && idx < VerDataMax) {
        *pAttribId = VerData[idx].attribute;
    }

    return status;
}


NTSTATUS ValidateProtocolSequence(PSDP_NODE pOuterSeq, PPSM_LIST pPsmList)
{
    PPSM_PROTOCOL_PAIR pppp;
    PSDP_NODE   pSeqProt, pUuid, pParam;
    PLIST_ENTRY entry;
    GUID        uuid;
    BOOLEAN     psmFromUuid = FALSE,
                noL2Cap = FALSE;

    pppp = pPsmList->list + pPsmList->count;

    //
    // Get the first element in the sequence, which is itself a sequence
    // (which contains a UUID and optional elements)
    //
    entry = pOuterSeq->u.sequence.Link.Flink;
    pSeqProt = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
    ASSERT(pSeqProt->hdr.Type == SDP_TYPE_SEQUENCE);

    entry = pSeqProt->u.sequence.Link.Flink; 
    pUuid = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
    ASSERT(pUuid->hdr.Type == SDP_TYPE_UUID);

    SdpNormalizeUuid(pUuid, &uuid);

    if (IsEqualUuid(&uuid, &L2CAP_PROTOCOL_UUID)) {
        //
        // Check to see if we are at the end of the inner sequence (pSeqProt)
        //
        if (pUuid->hdr.Link.Flink == &pSeqProt->u.sequence.Link) {
            //
            // Must rely on the next protocol in the list to indicate the PSM.  
            // This is because all of the currently published profiles do not 
            // require a PSM in their records
            //
            // If this is the last sequence in the outer seq, error
            //
            if (pSeqProt->hdr.Link.Flink == &pOuterSeq->u.sequence.Link) {
                return STATUS_INVALID_PARAMETER;
            }

            psmFromUuid = TRUE;
        }
        else {
            //
            // Got a PSM!
            //
            pParam = CONTAINING_RECORD(pUuid->hdr.Link.Flink, SDP_NODE, hdr.Link);
            ASSERT(pParam->hdr.Type == SDP_TYPE_UINT);
            pppp->psm = pParam->u.uint16;
        }
    }
    else {
        noL2Cap = TRUE; 
    }

    //
    // If we need a psm or there was no l2cap and there aren't any more protocols,
    // then fail it
    //
    // ISSUE: 
    //  1 this needs to be fixed for SCO connections!
    //      (what the hell do SCO SDP records look like?)
    //  2 should SDP records w/out l2cap be failed?  in the 1.0b profile spec, 
    //      each profile requires it.  in the future, will we be bitten by this 
    //      assumption if we enforce it now???
    //
    if ((psmFromUuid || noL2Cap) && 
        pSeqProt->hdr.Link.Flink == &pOuterSeq->u.sequence.Link) {
        return STATUS_INVALID_PARAMETER;
    }

    entry = pSeqProt->hdr.Link.Flink; 
    pSeqProt = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
    ASSERT(pSeqProt->hdr.Type == SDP_TYPE_SEQUENCE);

    entry = pSeqProt->u.sequence.Link.Flink; 
    pUuid = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
    ASSERT(pUuid->hdr.Type == SDP_TYPE_UUID);

    SdpNormalizeUuid(pUuid, &uuid);

    if (psmFromUuid) {
        if (IsEqualUuid(&uuid, &RFCOMM_PROTOCOL_UUID)) {
            pppp->psm = PSM_RFCOMM;
        }
        else if (IsEqualUuid(&uuid, &TCSBIN_PROTOCOL_UUID)) {
            pppp->psm = PSM_TCS_BIN;
        }
        else if (IsEqualUuid(&uuid, &SDP_PROTOCOL_UUID)) {
            //
            // we don't allow anyone to submit an SDP record locally
            //
            return STATUS_INVALID_PARAMETER;
        }
        else {
            //
            // Don't know how to map the PSM from the protocol
            //
            return STATUS_INVALID_PARAMETER;
        }
    }

    RtlCopyMemory(&pppp->protocol, &uuid, sizeof(uuid));
    pPsmList->count++;

    return STATUS_SUCCESS;
}

NTSTATUS SdpValidateProtocolContainer(PSDP_NODE pContainer, PPSM_LIST pPsmList)
{
    if (pContainer->hdr.Type == SDP_TYPE_SEQUENCE) {
        return ValidateProtocolSequence(pContainer, pPsmList);
    }
    else {
        NTSTATUS status;
        PLIST_ENTRY entry;
        PSDP_NODE pSeq;

        for (entry = pContainer->u.alternative.Link.Flink;
             entry != &pContainer->u.alternative.Link;
             entry = entry->Flink) {
            pSeq = CONTAINING_RECORD(entry, SDP_NODE, hdr.Link);
            ASSERT(pSeq->hdr.Type == SDP_TYPE_SEQUENCE);
            status = ValidateProtocolSequence(pSeq, pPsmList);
            if (!NT_SUCCESS(status)) {
                return status;
            }
        }

        return STATUS_SUCCESS;
    }
}

⌨️ 快捷键说明

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