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

📄 parseutil.cpp

📁 三星2440原版bsp
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                }
                return STATUS_INVALID_PARAMETER;
            }

            INC_STREAM(dataSize);
            break;

        case SDP_TYPE_URL:
        case SDP_TYPE_STRING:
        case SDP_TYPE_SEQUENCE:
        case SDP_TYPE_ALTERNATIVE:
            //
            // valid indecies are 5, 6 ,7
            //
            // Retrieve the size, convert it to little endian, and then compute
            // the total size for this element (amount of storage for the size
            // + the size itself).  
            //
            // Furthermore, make sure we have enough storage for the stored size.
            //
            switch (sizeIndex) {
            case 5:
                elementSize = ((ULONG) *Stream);  
                dataSize = 1 + elementSize;
                break;

            case 6:
                if (Size < 2) {
                    if (ARGUMENT_PRESENT(ErrorByte)) {
                        *ErrorByte = Stream - origStream;
                    }
                    return STATUS_INVALID_PARAMETER;
                }
                RtlRetrieveUshort(&usVal, Stream);
                elementSize = (ULONG) RtlUshortByteSwap(usVal);
                dataSize = 2 + elementSize;
                break;

            case 7:
                if (Size < 4) {
                    if (ARGUMENT_PRESENT(ErrorByte)) {
                        *ErrorByte = Stream - origStream;
                    }
                    return STATUS_INVALID_PARAMETER;
                }
                RtlRetrieveUlong(&ulVal, Stream);
                elementSize = RtlUlongByteSwap(ulVal);
                dataSize = 4 + elementSize;
                break;

            default:
                if (ARGUMENT_PRESENT(ErrorByte)) {
                    *ErrorByte = Stream - origStream;
                }
                return STATUS_INVALID_PARAMETER;
            }

            //
            // Finally, check to see if there is enough storage for the storage
            // for the size + the actual amount of data.
            // 
            if (dataSize > Size) {
                if (ARGUMENT_PRESENT(ErrorByte)) {
                    *ErrorByte = Stream - origStream;
                }
                return STATUS_INVALID_PARAMETER;
            }

            if (type == SDP_TYPE_STRING || type == SDP_TYPE_URL) {
                //
                // Increment past the string  / URL data
                //
                if (ARGUMENT_PRESENT(ExtraPool)) {
                    (*ExtraPool) += ROUND_SIZE(elementSize);
                }
                INC_STREAM(dataSize);
            }
            else {
                //
                // Validate the sequence / alternative list, increment only past 
                // the storage that holds the size
                //
                INC_STREAM((dataSize - elementSize));
            }
            break;

        default:
            // there is an error in the stream
            if (ARGUMENT_PRESENT(ErrorByte)) {
                *ErrorByte = Stream - origStream;
            }
            return STATUS_INVALID_PARAMETER;
        }
    }

    return STATUS_SUCCESS;
}

ULONG ComputeNumberOfEntries(PUCHAR Stream, ULONG Size, UCHAR FullParse)
{
    ULONG dataSize, elementSize, ulVal, numEntries = 0;
    USHORT usVal;
    UCHAR type, sizeIndex;

    while (Size) {
        SdpRetrieveHeader(Stream, type, sizeIndex);

        INC_STREAM(1);

        numEntries++;

        switch (type) {
        case SDP_TYPE_NIL:
            break;

        case SDP_TYPE_BOOLEAN:
            INC_STREAM(1);
            break;

        case SDP_TYPE_UINT:
        case SDP_TYPE_INT:
            //
            // valid size indicides are 0 - 4.
            //
            switch (sizeIndex) {
            case 0:  dataSize = 1; break;
            case 1:  dataSize = 2; break;
            case 2:  dataSize = 4; break;
            case 3:  dataSize = 8; break;
            case 4:  dataSize = 16; break;
            }

            INC_STREAM(dataSize);
            break;

        case SDP_TYPE_UUID:
            //
            // valid indecies are 1,2,4
            //
            switch (sizeIndex) {
            case 1:  dataSize = 2; break;
            case 2:  dataSize = 4; break;
            case 4:  dataSize = 16; break;
            }

            INC_STREAM(dataSize);
            break;

        case SDP_TYPE_URL:
        case SDP_TYPE_STRING:
        case SDP_TYPE_SEQUENCE:
        case SDP_TYPE_ALTERNATIVE:
            //
            // valid indecies are 5, 6 ,7
            //
            // Retrieve the size, convert it to little endian, and then compute
            // the total size for this element (amount of storage for the size
            // + the size itself).  
            //
            switch (sizeIndex) {
            case 5:
                elementSize = (ULONG) *Stream;  
                dataSize = 1 + elementSize;
                break;

            case 6:
                RtlRetrieveUshort(&usVal, Stream);
                elementSize = (ULONG) RtlUshortByteSwap(usVal);
                dataSize = 2 + elementSize;
                break;

            case 7:
                RtlRetrieveUlong(&ulVal, Stream);
                elementSize = RtlUlongByteSwap(ulVal);
                dataSize = 4 + elementSize;
            }

            if (type == SDP_TYPE_STRING || type == SDP_TYPE_URL || !FullParse) {
                //
                // Increment past the string  / URL data / container
                // (if we are not fully parsing)
                //
                INC_STREAM(dataSize);
            }
            else {
                //
                // Validate the sequence / alternative list, increment only past 
                // the storage that holds the size
                //
                INC_STREAM((dataSize - elementSize));
            }
            break;
        }
    }

    return numEntries;
}

SDP_ERROR MapNtStatusToSdpError(NTSTATUS Status)
{
    switch (Status) {
    case STATUS_INVALID_PARAMETER:
        return SDP_ERROR_INVALID_REQUEST_SYNTAX;

    case STATUS_INSUFFICIENT_RESOURCES:
        return SDP_ERROR_INSUFFICIENT_RESOURCES; 

    default:
        ASSERT(FALSE);
        return SDP_ERROR_INVALID_REQUEST_SYNTAX;
    }
}

VOID Sdp_InitializeListHead(PLIST_ENTRY ListHead)
{
    InitializeListHead(ListHead);
}

UCHAR Sdp_IsListEmpty(PLIST_ENTRY ListHead)
{
    return IsListEmpty(ListHead);
}

VOID Sdp_InsertHeadList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
{
    InsertHeadList(ListHead, Entry);
}

VOID Sdp_InsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry)
{
    InsertTailList(ListHead, Entry);
}


VOID Sdp_InsertEntryList(PLIST_ENTRY Previous, PLIST_ENTRY Entry)
{
    InsertEntryList(Previous, Entry); 
}

PLIST_ENTRY Sdp_RemoveHeadList(PLIST_ENTRY ListHead)
{
    return RemoveHeadList(ListHead);
}

VOID Sdp_RemoveEntryList(PLIST_ENTRY Entry)
{
    RemoveEntryList(Entry);
}

struct VerifyRecord {
    VerifyRecord() {
        isAttribId = TRUE;
        done = FALSE;
        seenFirstElem = FALSE;
    }

    UCHAR seenFirstElem;
    UCHAR isAttribId;
    UCHAR done;
};

NTSTATUS 
VerifyIsRecordWalk(
    VerifyRecord *verify,
    UCHAR DataType,
    ULONG DataSize,
    PVOID Data,
    ULONG DataStorageSize
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    if (verify->done) {
        //
        // if we encounter any stream elements after we are done, than this is 
        // an invalid stream
        //
        return STATUS_INVALID_PARAMETER;
    }
    else if (verify->seenFirstElem == FALSE) {
        if (DataType == SDP_TYPE_SEQUENCE) {
            verify->seenFirstElem = TRUE;
        }
        else {
            //
            // first item in the list must be a sequence
            //
            status = STATUS_INVALID_PARAMETER;
        }
    }
    else {
        if (verify->isAttribId) {
            if (DataType == SDP_TYPE_SEQUENCE && Data == NULL) {
                //
                // end of the sequence
                //
                verify->done = TRUE;
                return STATUS_SUCCESS;
            }
            else if (DataType != SDP_TYPE_UINT && DataSize != sizeof(USHORT)) {
                //
                // not a attrib ID where we expect it, bad stream!
                //
                return STATUS_INVALID_PARAMETER;
            }
        }
        else {
            if (DataType == SDP_TYPE_SEQUENCE ||
                DataType == SDP_TYPE_ALTERNATIVE) {
                status = STATUS_REPARSE_POINT_NOT_RESOLVED;
            }
        }

        verify->isAttribId = !verify->isAttribId;
    }

    return status;
}

NTSTATUS SdpIsStreamRecord(PUCHAR Stream, ULONG Size)
{
    NTSTATUS status;

    status = ValidateStream(Stream, Size, NULL, NULL, NULL);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    VerifyRecord vr;

    return SdpWalkStream(Stream,
                         Size,
                         (PSDP_STREAM_WALK_FUNC) VerifyIsRecordWalk,
                         &vr);
}

void SdpNormalizeUuid(PSDP_NODE pUuid, GUID* uuid)
{
    if (pUuid->hdr.SpecificType == SDP_ST_UUID128) {
        RtlCopyMemory(uuid, &pUuid->u.uuid128, sizeof(GUID));
    }
    else if (pUuid->hdr.SpecificType == SDP_ST_UUID32) {
        RtlCopyMemory(uuid, &Bluetooth_Base_UUID, sizeof(GUID));
        uuid->Data1 += pUuid->u.uuid32;
    }
    else {
        RtlCopyMemory(uuid, &Bluetooth_Base_UUID, sizeof(GUID));
        uuid->Data1 += pUuid->u.uuid16;
    }
}


⌨️ 快捷键说明

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