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

📄 sdpdbserver.cpp

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

    SdpAttributeRange * pAttr =
        pAttribSrch->pRange + pAttribSrch->currentAttribute;

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

        RtlRetrieveUshort(&uint16, Data);
        pAttr->minAttribute = pAttr->maxAttribute = RtlUshortByteSwap(uint16);
    }
    else {
        ULONG uint32;

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

        pAttr->minAttribute = (USHORT) ((uint32 & 0xFFFF0000) >> 16);
        pAttr->maxAttribute = (USHORT) (uint32 & 0xFFFF);
    }

    pAttribSrch->currentAttribute++;

    return STATUS_SUCCESS;
}


NTSTATUS 
SdpDatabase::ServiceAttributeRequestResponseRemote(
    IN ULONG serviceHandle,
    IN UCHAR *pAttribIdListStream,
    IN ULONG streamSize,
    OUT UCHAR **ppAttributeListStream,
    OUT ULONG *pAttributeListSize,
    OUT PVOID * ppOriginalAlloc,
    OUT PSDP_ERROR pSdpError
    )
{
    SdpAttribSearch attribSrch;
    NTSTATUS status;

    PAGED_CODE();

    status = attribSrch.RetrieveAttributes(pAttribIdListStream, streamSize);
    if (!NT_SUCCESS(status)) {
        *pSdpError = MapNtStatusToSdpError(status);
        return status;
    }

    return ServiceAttributeRequestResponse(serviceHandle,
                                           &attribSrch,
                                           ppAttributeListStream,
                                           pAttributeListSize,
                                           ppOriginalAlloc,
                                           pSdpError);
}

NTSTATUS 
SdpDatabase::ServiceAttributeRequestResponseLocal(
    IN ULONG serviceHandle,
    IN SdpAttributeRange *pRange,
    IN ULONG numRange,
    OUT UCHAR **ppAttributeListStream,
    OUT ULONG *pAttributeListSize,
    OUT PVOID * ppOriginalAlloc
    )
{
    SdpAttribSearch attribSrch;
    SDP_ERROR sdpError;
    
    attribSrch.SetAttributes(pRange, numRange);

    return ServiceAttributeRequestResponse(serviceHandle,
                                           &attribSrch,
                                           ppAttributeListStream,
                                           pAttributeListSize,
                                           ppOriginalAlloc,
                                           &sdpError);
}

NTSTATUS 
SdpDatabase::ServiceAttributeRequestResponse(
    IN ULONG serviceHandle,
    SdpAttribSearch *pAttribSearch,
    OUT UCHAR **ppAttributeListStream,
    OUT ULONG *pAttributeListSize,
    OUT PVOID * ppOriginalAlloc,
    OUT PSDP_ERROR pSdpError
    )
{
    ServiceRecord *pRecord;
    PSDP_STREAM_ENTRY pStreamEntry;
    NTSTATUS status = STATUS_SUCCESS;

    BOOLEAN foundRecord = FALSE;

    pStreamEntry = NULL;
    m_ServiceRecordList.Lock();

    status = STATUS_UNSUCCESSFUL;

    for (pRecord = m_ServiceRecordList.GetHead();
         pRecord != NULL;
         pRecord = m_ServiceRecordList.GetNext(pRecord)) {

        if (pRecord->recordHandle == serviceHandle) {
            _DbgPrintF(DBG_SDP_INFO,
                       ("AttributeRequest found record handle 0x%08x", serviceHandle));

            foundRecord = TRUE;

            status = pAttribSearch->FindElements(
                pRecord->pStream,
                pRecord->streamSize,
                &pStreamEntry,
                pSdpError);

            //
            // FindElements will return success even if there was no match.  If
            // it returns an error, than that means there was either an invalid
            // search or there was a problem allocating pool
            //
            if (!NT_SUCCESS(status)) {
                _DbgPrintF(DBG_SDP_WARNING, ("search was not successful, 0x%x", status));
                *pSdpError = MapNtStatusToSdpError(status);
            }
            break;
        }
    }

    m_ServiceRecordList.Unlock();

    if (foundRecord == TRUE) {
        if (!NT_SUCCESS(status)) {

            _DbgPrintF(DBG_SDP_WARNING, ("search was successful, but an error occurred, 0x%x", status));
            if (pStreamEntry) {
                ExFreePool(pStreamEntry);
                pStreamEntry = NULL;
            }

            *ppAttributeListStream = NULL;
            *pAttributeListSize = 0x0;
        }
        else if (pStreamEntry != NULL){
            //
            // there are search results
            //
            _DbgPrintF(DBG_SDP_INFO,
                       ("search was successful, result is %d long", pStreamEntry->streamSize));

            *ppAttributeListStream = pStreamEntry->stream;
            *pAttributeListSize = pStreamEntry->streamSize;
            *ppOriginalAlloc = pStreamEntry;
        }
        else {
            //
            // We didn't find anything so we need to create an empty sequence
            // and send it back
            //
            _DbgPrintF(DBG_SDP_INFO, ("search was successful, no match though"));

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
            UCHAR *pStream = new (PagedPool, SDP_TAG) UCHAR[2];
#else
            UCHAR *pStream = (UCHAR*) ExAllocatePoolWithTag(0,2*sizeof(UCHAR),0);
            if (pStream)
                memset(pStream,0,sizeof(UCHAR[2]));
#endif
            if (*ppAttributeListStream) {
                *ppOriginalAlloc = pStream; 
                *ppAttributeListStream = pStream;
                *pAttributeListSize = 2;

                WriteVariableSizeToStream(SDP_TYPE_SEQUENCE, 0, pStream);

                ASSERT(NT_SUCCESS(status));
            }
            else {
                status = STATUS_INSUFFICIENT_RESOURCES;
                *pSdpError = MapNtStatusToSdpError(status);
            }
        }
    }
    else {
        _DbgPrintF(DBG_SDP_INFO,
                   ("did not find the specified record handle (0x%08x) in the DB",
                    serviceHandle));
        *pSdpError = SDP_ERROR_INVALID_RECORD_HANDLE;
        status = STATUS_UNSUCCESSFUL;
    }

    return status;
}

NTSTATUS 
SdpDatabase::ServiceSearchAttributeResponseLocal(
    IN SdpQueryUuid *pUuid,
    IN UCHAR numUuid,
    IN SdpAttributeRange *pRange,
    IN ULONG numRange,
    OUT UCHAR **ppAttributeLists,           
    OUT ULONG *pAttributeListsByteCount
    )
{
    SdpUuidSearch uuidSrch;
    SdpAttribSearch attribSrch;
    SDP_ERROR sdpError;

    uuidSrch.SetUuids(pUuid, numUuid);
    attribSrch.SetAttributes(pRange, numRange);

    return ServiceSearchAttributeResponse(&uuidSrch,
                                          &attribSrch,
                                          ppAttributeLists,
                                          pAttributeListsByteCount,
                                          &sdpError,
                                          TRUE);
}

NTSTATUS
SdpDatabase::ServiceSearchAttributeResponseRemote(
    IN UCHAR *pServiceSearchStream,
    IN ULONG serviceSearchStreamSize,
    IN UCHAR *pAttributeIdStream,
    IN ULONG attributeIdStreamSize,
    OUT UCHAR **ppAttributeLists,
    OUT ULONG *pAttributeListsByteCount,
    OUT PSDP_ERROR pSdpError
    )
{
    SdpUuidSearch uuidSrch;
    SdpAttribSearch attribSrch;

    NTSTATUS status;

    status = uuidSrch.RetrieveUuids(pServiceSearchStream, serviceSearchStreamSize);
    if (!NT_SUCCESS(status)) {
        *pSdpError = MapNtStatusToSdpError(status);
        return status;
    }

    status = attribSrch.RetrieveAttributes(pAttributeIdStream, attributeIdStreamSize);
    if (!NT_SUCCESS(status)) {
        *pSdpError = MapNtStatusToSdpError(status);
        return status;
    }

    return ServiceSearchAttributeResponse(&uuidSrch,
                                          &attribSrch,
                                          ppAttributeLists,
                                          pAttributeListsByteCount,
                                          pSdpError,
                                          FALSE);
}

NTSTATUS
SdpDatabase::ServiceSearchAttributeResponse(
    IN SdpUuidSearch *pUuidSearch,
    IN SdpAttribSearch *pAttribSearch,
    OUT UCHAR **ppAttributeLists,           // must be freed when xmit is finished
    OUT ULONG *pAttributeListsByteCount,
    OUT PSDP_ERROR pSdpError,
    IN BOOLEAN Local
    )
{
    PAGED_CODE();

    NTSTATUS status = STATUS_SUCCESS;
    LIST_ENTRY head;

    PLIST_ENTRY pListEntry;
    PSDP_STREAM_ENTRY pStreamEntry;

    *ppAttributeLists = NULL;
    *pAttributeListsByteCount = 0;

    InitializeListHead(&head);
    ServiceRecord *pRecord;
    ULONG streamSize = 0;

    m_ServiceRecordList.Lock();

    for (pRecord = m_ServiceRecordList.GetHead();
         pRecord != NULL;
         pRecord = m_ServiceRecordList.GetNext(pRecord)) {

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
        if (Local == FALSE &&
            pRecord->fOptions & SERVICE_OPTION_DO_NOT_PUBLISH) {
            //
            // Record sumbitter did not want this SDP record published to the 
            // world.  Skip it.
            //
            continue;
        }
#endif

        if (pUuidSearch->SearchStream(pRecord->pStream, pRecord->streamSize)) {
            pStreamEntry = NULL;

            status = pAttribSearch->FindElements(
                pRecord->pStream,
                pRecord->streamSize,
                &pStreamEntry,
                pSdpError);

            if (NT_SUCCESS(status)) {
                if (pStreamEntry != NULL) {
                    //
                    // pStreamEntry will be freed when we exit this function
                    //
                    InsertTailList(&head, &pStreamEntry->link);
                    streamSize += pStreamEntry->streamSize;
                }
                else {
                    //
                    // success will be returned even if there is no match
                    //
                    ;
                }
            }
            else {
                //
                // if there was an error allocating pool or there was something
                // incorrectly formatted, we will drop into here
                //
                break;
            }
        }
    }

    m_ServiceRecordList.Unlock();

    if (NT_SUCCESS(status)) {
        ULONG totalSize;

        //
        // compute the total amout of stream required
        //
        totalSize = streamSize + (USHORT) GetContainerHeaderSize(streamSize);

        
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
        UCHAR *pStream = new(NonPagedPool, SDP_TAG) UCHAR[totalSize];
#else
        UCHAR *pStream = (PUCHAR) ExAllocatePoolWithTag(0,sizeof(UCHAR)*totalSize,0);
        if (pStream)
            memset(pStream,0,sizeof(UCHAR)*totalSize);
#endif

        if (pStream) {
            *ppAttributeLists = pStream;
            *pAttributeListsByteCount = totalSize;

            pStream  = WriteVariableSizeToStream(SDP_TYPE_SEQUENCE, streamSize, pStream);

            ASSERT(streamSize == 0 || !IsListEmpty(&head));

            for (pListEntry = head.Flink;
                 pListEntry != &head;
                 pListEntry = pListEntry->Flink) {

                pStreamEntry =
                    CONTAINING_RECORD(pListEntry, SDP_STREAM_ENTRY, link);

                RtlCopyMemory(pStream,
                              pStreamEntry->stream,
                              pStreamEntry->streamSize);

                pStream += pStreamEntry->streamSize;
            }

            ASSERT((ULONG) (pStream - *ppAttributeLists) == totalSize);
        }
        else {
            status = STATUS_INSUFFICIENT_RESOURCES;
            *pSdpError = MapNtStatusToSdpError(status);
        }
    }
    else {
        *pSdpError = MapNtStatusToSdpError(status);
    }

    while (!IsListEmpty(&head)) {
        pListEntry = RemoveHeadList(&head);
        ExFreePool( CONTAINING_RECORD(pListEntry, SDP_STREAM_ENTRY, link) );
    }

    return status;
}

⌨️ 快捷键说明

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