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

📄 sdpdbserver.cpp

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

    //
    // clean up
    //
    while (!hl.IsEmpty()) {
        phe = hl.RemoveHead();
        delete phe;
    }

    return status;
}

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
NTSTATUS
SdpDatabase::ServiceSearchRequestResponseCached(
    HANDLE hDeviceCache,
    SdpQueryUuid *pUuid,
    UCHAR numUuid,
    USHORT maxRecordsRequested,
    ULONG **ppResultStream,         // must be freed when xmit is finished
    USHORT *pRecordCount
    )
{
    NTSTATUS status;
    SdpUuidSearch uuidSrch;
    SDP_ERROR sdpError;
    ULONG sizeFull, sizePartial;
    ULONG numValues;
    USHORT numFound;
    PKEY_FULL_INFORMATION pKeyFullInfo;
    PKEY_VALUE_PARTIAL_INFORMATION pKeyPartialInfo;
    PUCHAR pFull, pPartial;


    PAGED_CODE();

    uuidSrch.SetUuids(pUuid, numUuid);

    SdpPrint(SDP_DBG_UUID_TRACE, ("ServiceSearchRequestResponseCached enter\n"));

    *ppResultStream = NULL;
    *pRecordCount = 0;

    numFound = 0;

    status = STATUS_SUCCESS;

    sizeFull = 0;
    status = ZwQueryKey(hDeviceCache, KeyFullInformation, NULL, 0, &sizeFull);
    if (!NT_SUCCESS(status)) {
    }

    pFull = new  (PagedPool) UCHAR[sizeFull];
    pKeyFullInfo = (PKEY_FULL_INFORMATION) pFull;
    if (pKeyFullInfo == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = ZwQueryKey(hDeviceCache, KeyFullInformation, pKeyFullInfo, sizeFull, &sizeFull);
    if (!NT_SUCCESS(status)) {
        delete[] pFull;
        return status;
    }

    // MaxValueDataLen 
    sizePartial = pKeyFullInfo->MaxValueDataLen +
                  sizeof (KEY_VALUE_PARTIAL_INFORMATION);

    pPartial = new (PagedPool) UCHAR[sizePartial];
    pKeyPartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION) pPartial;
                       
    numValues = pKeyFullInfo->Values;
        
    //
    // Iterate over each cached record.  If ALL the UUIDs in the search are found
    // then report the search record back to the requestor
    //
    HandleList hl;
    HandleEntry *phe;

    for (ULONG i = 0; i < numValues; i++) {
        ULONG size;

        status = ZwEnumerateValueKey(hDeviceCache,
                                     i,
                                     KeyValuePartialInformation,
                                     pKeyPartialInfo,
                                     sizePartial,
                                     &size);

        if (NT_SUCCESS(status)) {
            PUCHAR pStream = pKeyPartialInfo->Data;
            ULONG sizeStream = pKeyPartialInfo->DataLength;
            USHORT id;

            status = ValidateStream(pStream, sizeStream, NULL);
            if (!NT_SUCCESS(status)) {
                continue;
            }

            status = SdpVerifyServiceRecord(pStream,
                                            sizeStream,
                                            VERIFY_CHECK_MANDATORY_REMOTE,
                                            &id);
            if (!NT_SUCCESS(status)) {
                continue;
            }

            if (uuidSrch.SearchStream(pStream, sizeStream)) {
                PUCHAR pStreamHandle;
                ULONG sizeHandle;

                status = SdpFindAttributeInStream(pStream, 
                                                  sizeStream,
                                                  SDP_ATTRIB_RECORD_HANDLE,
                                                  &pStreamHandle,
                                                  &sizeHandle);

                if (NT_SUCCESS(status)) {
                    ASSERT(sizeHandle == sizeof(ULONG) + sizeof(UCHAR));

                    pStreamHandle++;
                    sizeHandle--;

                    ULONG recordHandle;

                    RtlRetrieveUlong(&recordHandle, pStreamHandle);
                    recordHandle = RtlUlongByteSwap(recordHandle);

                    SdpPrint(SDP_DBG_UUID_INFO,
                             ("uuid search, FOUND match in cached record %08x\n",
                              recordHandle));

                    phe = new (PagedPool, SDP_TAG) HandleEntry(recordHandle);
                    if (phe) {
                        hl.AddTail(phe);
                        numFound++;
                    }

                    //
                    // Found as many as the requestor asked for
                    //
                    if (numFound == maxRecordsRequested) {
                        break;
                    }
                }

            }
        }
    }

    if (numFound > 0) {
        PULONG pResult;

        //
        // TODO:  I can optimize this by just returning the linked list and then
        //      pulling values off of that instead of allocating pool again here
        //
        pResult = (ULONG *) ExAllocatePoolWithTag(NonPagedPool, 
                                                  numFound * sizeof(ULONG),
                                                  SDP_TAG);
        *ppResultStream = pResult;

        if (*ppResultStream == NULL) {
            SdpPrint(SDP_DBG_UUID_ERROR,
                     ("could not alloc pool for a cached ServiceSearch response\n"));

            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        else {
            *pRecordCount = numFound;
            phe = hl.GetHead();

            ASSERT(hl.GetCount() == numFound);

            for (USHORT i = 0; i < numFound; i++, phe = hl.GetNext(phe)) {
                pResult[i] = phe->handle;
            }
        }
    }

    //
    // clean up
    //
    while (!hl.IsEmpty()) {
        phe = hl.RemoveHead();
        delete phe;
    }

    if (pFull) {
        delete[] pFull;
        pFull = NULL;
        pKeyFullInfo = NULL;
    }
    if (pPartial) {
        delete[] pPartial;
        pPartial = NULL;
        pKeyPartialInfo = NULL;
    }

    return status;
}
#endif  // UNDER_CE

struct SdpAttribSearch {
    SdpAttribSearch() { ZERO_THIS(); }

    ~SdpAttribSearch()
    {
        if (pRange && ownRange) {
            delete[] pRange;
            pRange = NULL;
        }
    }

    void SetAttributes(SdpAttributeRange *pOrigRange, ULONG numRange)
    {
        ownRange = FALSE;
        pRange = pOrigRange;
        numAttributes = numRange;
    }

    NTSTATUS RetrieveAttributes(PUCHAR pStream, ULONG streamSize);

    NTSTATUS FindElements(PUCHAR pStream,
                          ULONG streamSize,
                          PSDP_STREAM_ENTRY *ppEntry,
                          PSDP_ERROR pSdpError)
    {
        PAGED_CODE();

        return SdpFindAttributeSequenceInStream(
                pStream,
                streamSize,
                pRange,
                numAttributes,
                ppEntry,
                pSdpError);
    }

    static NTSTATUS CountAttributesInSearchStreamWalk(
        SdpAttribSearch * pAttribSrch,
        UCHAR DataType,
        ULONG DataSize,
        PUCHAR Data,
        ULONG DataStorageSize);

    static NTSTATUS RetrieveAttributesInSearchStreamWalk(
        SdpAttribSearch *pAttribSrch,
        UCHAR DataType,
        ULONG DataSize,
        PUCHAR Data,
        ULONG DataStorageSize);

    SdpAttributeRange *pRange;

    ULONG numAttributes;
    ULONG currentAttribute;
    USHORT minAttrib;

    BOOLEAN ownRange;
};

NTSTATUS SdpAttribSearch::RetrieveAttributes(PUCHAR pStream, ULONG streamSize)
{
    PAGED_CODE();

    NTSTATUS status;

    status = SdpVerifySequenceOf(
        pStream,
        streamSize,
        SDP_TYPE_UINT,
        NULL,
        NULL,
        (PSDP_STREAM_WALK_FUNC) CountAttributesInSearchStreamWalk,
        (PVOID) this);

    if (!NT_SUCCESS(status)) {
        return status;
    }
    else if (numAttributes == 0) {
        return STATUS_INVALID_PARAMETER;
    }

    ownRange = TRUE;

    
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    pRange = new (NonPagedPool, 'ApdS') SdpAttributeRange[numAttributes];
#else
    pRange = new SdpAttributeRange[numAttributes];
    if (pRange)
        memset(pRange,0,sizeof(SdpAttributeRange)*numAttributes);
#endif
    if (pRange == NULL) {
        SdpPrint(SDP_DBG_ATTRIB_ERROR, ("could not alloc pool for a range list\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    return SdpVerifySequenceOf(
        pStream,
        streamSize,
        SDP_TYPE_UINT,
        NULL,
        NULL,
        (PSDP_STREAM_WALK_FUNC) RetrieveAttributesInSearchStreamWalk,
        (PVOID) this);
}

NTSTATUS 
SdpAttribSearch::CountAttributesInSearchStreamWalk(
    SdpAttribSearch *pAttribSrch,
    UCHAR DataType,
    ULONG DataSize,
    PUCHAR Data,
    ULONG DataStorageSize
    )
{
    PAGED_CODE();

    if (DataSize == sizeof(USHORT)) {
        USHORT uint16;

        RtlRetrieveUshort(&uint16, Data);
        uint16 = RtlUshortByteSwap(uint16);

        if (pAttribSrch->numAttributes != 0 && uint16 <= pAttribSrch->minAttrib) {
            SdpPrint(SDP_DBG_ATTRIB_ERROR, ("out of order attrib search (single attrib)\n"));
            return STATUS_INVALID_PARAMETER;
        }

        pAttribSrch->minAttrib = uint16;
        pAttribSrch->numAttributes++;
    }
    else if (DataSize == sizeof(ULONG)) {
        ULONG uint32;
        USHORT minAttrib, maxAttrib;

        RtlRetrieveUlong(&uint32, Data);
        uint32 = RtlUlongByteSwap(uint32);

        minAttrib = (USHORT) ((uint32 & 0xFFFF0000) >> 16);
        maxAttrib = (USHORT) (uint32 & 0xFFFF);

        if (maxAttrib <= minAttrib) {
            //
            // max is less than min???
            //
            SdpPrint(SDP_DBG_ATTRIB_ERROR, ("out of order attrib search (range attrib)\n"));
            return STATUS_INVALID_PARAMETER;
        }
        else if (pAttribSrch->numAttributes != 0 &&
                 minAttrib <= pAttribSrch->minAttrib) {
            //
            // ranges are overlapping
            //
            SdpPrint(SDP_DBG_ATTRIB_ERROR, ("overlapping attrib search\n"));
            return STATUS_INVALID_PARAMETER;
        }

        pAttribSrch->minAttrib = maxAttrib;
        pAttribSrch->numAttributes++;
    }
    else {
        SdpPrint(SDP_DBG_ATTRIB_ERROR, ("wrong size int (%d)\n", DataSize));
        return STATUS_INVALID_PARAMETER;
    }

    return STATUS_SUCCESS;
}

NTSTATUS
SdpAttribSearch::RetrieveAttributesInSearchStreamWalk(
    SdpAttribSearch *pAttribSrch,
    UCHAR DataType,
    ULONG DataSize,
    PUCHAR Data,
    ULONG DataStorageSize
    )
{
    PAGED_CODE();

	if (DataType != SDP_TYPE_UINT) {
		return STATUS_SUCCESS;

⌨️ 快捷键说明

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