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

📄 sdpdb.cpp

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

    while (!sdl.IsEmpty()) {
        pRecord = sdl.RemoveHead();
        delete pRecord;
    }
}
#endif  // defined (UNDER_CE) || defined (WINCE_EMULATION)

void SdpDatabase::AlterDatabaseState()
{
    NTSTATUS status; 
    ULONG val, size;
    PUCHAR pStream;

    val = RtlUlongByteSwap(InterlockedIncrement((PLONG) &m_dbState)); 

    //
    // DB lock is held while this function is called
    //
    status = SdpFindAttributeInStream(m_pSdpRecord->pStream,
                                      m_pSdpRecord->streamSize,
                                      SDP_ATTRIB_SDP_DATABASE_STATE,
                                      &pStream,
                                      &size
                                      );

    //
    // The stream returned is the entire element, not just the element value, so 
    // we need to increment beyond the header
    //
    ASSERT(NT_SUCCESS(status));
    ASSERT(size == sizeof(val) + sizeof(UCHAR));

#if DBG
    UCHAR type, sizeIndex;
    SdpRetrieveHeader(pStream, type, sizeIndex);
    
    ASSERT(type == SDP_TYPE_UINT);
    ASSERT(sizeIndex == 2); 
#endif // DBG

    pStream++;

#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    KeWaitForSingleObject((PVOID) &m_dbStateSemaphore,
                          Executive,
                          KernelMode,
                          FALSE,
                          NULL);

    RtlCopyMemory(pStream, &val, sizeof(val));

    KeReleaseSemaphore(&m_dbStateSemaphore, (KPRIORITY) 0, 1, FALSE); 
#else
    RtlCopyMemory(pStream, &val, sizeof(val));
#endif
}

void SdpDatabase::FireWmiEvent(
    HANDLE recordHandle,
    SDP_DATABASE_EVENT_TYPE type
    )
{
#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    PSDP_DATABASE_EVENT pEvent = (PSDP_DATABASE_EVENT)
        ExAllocatePoolWithTag(PagedPool, sizeof(*pEvent), SDP_TAG); 

    if (pEvent) {
        DeviceLE *ple;

        pEvent->type = type;
        pEvent->handle = recordHandle;

        m_DeviceList.Lock();
        ple = m_DeviceList.GetHead();
        if (ple) {
            WmiFireEvent(ple->device,
                         (LPGUID) &GUID_BTHPORT_WMI_SDP_DATABASE_EVENT,
                         0,
                         sizeof(*pEvent),
                         pEvent);
        }
        else {
            ExFreePool(pEvent);
        }
        m_DeviceList.Unlock();
    }
#endif    // defined (UNDER_CE) || defined (WINCE_EMULATION)
}

NTSTATUS SdpDatabase::AddProtMux(GUID *protocol)
{
    ProtMux * ppm, *ppmIter;
    NTSTATUS status = STATUS_SUCCESS;


    #if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
    ppm = new(NonPagedPool, PM_TAG) ProtMux(protocol);
#else
    ppm = new ProtMux(protocol);
#endif

    if (ppm) {
        m_ServiceRecordList.Lock();

        for (ppmIter = m_ProtMuxList.GetHead();
             ppmIter != NULL;
             ppmIter = m_ProtMuxList.GetNext(ppmIter)) {
            if (IsEqualUuid(protocol, &ppmIter->protocol)) {
                status = STATUS_OBJECT_NAME_COLLISION; 
                break;
            }
        }

        if (NT_SUCCESS(status)) {
            m_ProtMuxList.AddTail(ppm);
            m_ServiceRecordList.Unlock();
        }
        else {
            m_ServiceRecordList.Unlock();
            delete ppm;
        }
    }
    else {
        status = STATUS_INSUFFICIENT_RESOURCES;
    }

    return status;
}

NTSTATUS SdpDatabase::RemoveProtMux(GUID *protocol)
{
    ProtMux *ppm;
    NTSTATUS status = STATUS_NOT_FOUND;

    m_ServiceRecordList.Lock();
    for (ppm = m_ProtMuxList.GetHead();
         ppm != NULL;
         ppm = m_ProtMuxList.GetNext(ppm)) {
        if (IsEqualUuid(protocol, &ppm->protocol)) {
            m_ProtMuxList.RemoveAt(ppm);
            break;
        }
    }
    m_ServiceRecordList.Unlock();

    if (NT_SUCCESS(status)) {
        delete ppm;
    }

    return status;
}

BOOLEAN SdpDatabase::IsProtocolMuxed(const GUID &protocol)
{
    ProtMux *ppm;

    for (ppm = m_ProtMuxList.GetHead();
         ppm != NULL;
         ppm = m_ProtMuxList.GetNext(ppm)) {

        if (IsEqualUuid(&ppm->protocol, &protocol)) {
            return TRUE;
        }
    }

    return FALSE;
}

NTSTATUS SdpDatabase::GetPsmInfo(USHORT psm, GUID *protocol, ULONG *serviceHandle)
{
    ServiceRecord *pRecord;
    NTSTATUS status = STATUS_NOT_FOUND;

    m_ServiceRecordList.Lock();

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

        for (ULONG i = 0; i < pRecord->psmList.count; i++) {
            if (psm == pRecord->psmList.list[i].psm) {
                *serviceHandle = pRecord->recordHandle;
                RtlCopyMemory(protocol,
                              &pRecord->psmList.list[i].protocol,
                              sizeof(GUID));
                status = STATUS_SUCCESS;
                break;
            }
        }

        if (NT_SUCCESS(status)) {
            break;
        }
    }
    
    m_ServiceRecordList.Unlock();

    return status;
}

NTSTATUS SdpDatabase::GetServiceClass(USHORT psm, GUID *serviceClass)
{
    // NOTE: If this function is ever called for WinCE, be sure to make sure
    // gpSdp (in sdpbase.cxx) has lock held.
    ServiceRecord *pRecord;
    NTSTATUS status = STATUS_NOT_FOUND;

    m_ServiceRecordList.Lock();

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

        for (ULONG i = 0; i < pRecord->psmList.count; i++) {
            if (psm == pRecord->psmList.list[i].psm) {
                if (IsProtocolMuxed(pRecord->psmList.list[i].protocol)) {
                    status = STATUS_PENDING;
                }
                else {
                    RtlCopyMemory(serviceClass,
                                  &pRecord->serviceClass,
                                  sizeof(GUID));

                    status = STATUS_SUCCESS;
                }
                break;
            }
        }

        if (NT_SUCCESS(status)) {
            break;
        }
    }
    
    m_ServiceRecordList.Unlock();

    return status;
}

ULONG SdpDatabase::GetNextRecordHandle()
{
    ULONG handle = (ULONG) InterlockedIncrement(&m_nextRecordHandle);
    if (handle == 0) {
        //
        // we have wrapped, goto the start, then increment
        //
        // ISSUE:  we should really find a hole in the records list, but we 
        //         worry about that when the time comes
        //
#if defined (UNDER_CE)
        InterlockedCompareExchange((LONG*)&m_nextRecordHandle,
                                   INIT_HANDLE_VALUE,
                                   0);
#else
        InterlockedCompareExchange((void **)&m_nextRecordHandle,
                                   (void *)INIT_HANDLE_VALUE,
                                   (void *)0);
#endif
        handle = (ULONG) InterlockedIncrement(&m_nextRecordHandle);
    }

    return handle;
}


#if ! (defined (UNDER_CE) || defined (WINCE_EMULATION))
extern "C"
NTSTATUS pSdpTreeFromStream(
    PUCHAR Stream,
    ULONG Size,
    PSDP_TREE_ROOT_NODE *Node
    )
{
    return SdpTreeFromStream(Stream, Size, Node, TRUE);
}

NTSTATUS SdpDatabase::HandleQI(PIRP Irp)
{
    PIO_STACK_LOCATION stack;
    NTSTATUS status;
    const GUID *pInterfaceType;

    status = Irp->IoStatus.Status;
    stack = IoGetCurrentIrpStackLocation(Irp);

    pInterfaceType = stack->Parameters.QueryInterface.InterfaceType; 

    if (IsEqualUuid(pInterfaceType, &GUID_BTHDDI_SDP_VALIDATE_INTERFACE)) {
        PBTHDDI_SDP_VALIDATE_INTERFACE pValidate = (PBTHDDI_SDP_VALIDATE_INTERFACE)
            stack->Parameters.QueryInterface.Interface;

        if (pValidate->Interface.Size != sizeof(*pValidate) ||
            pValidate->Interface.Version < 1                ||
            (pValidate->Validator != NULL &&
                 (pValidate->Flags & RVFI_VALID_FLAGS) == 0)) {
            status = STATUS_INVALID_PARAMETER; 
        }
        else if (pValidate->Validator == NULL) {
            //
            // removal
            //
            if (pValidate->Cookie == NULL) {
                status = STATUS_INVALID_PARAMETER; 
            }
            else {
                RecordValidator *prv;

                m_RecordValidatorList.Lock();
                for (prv = m_RecordValidatorList.GetHead();
                     prv != NULL;
                     prv = m_RecordValidatorList.GetNext(prv)) {
                    if ((PVOID) prv == pValidate->Cookie) {
                        m_RecordValidatorList.RemoveAt(prv);
                        break;
                    }
                }
                m_RecordValidatorList.Unlock();

                if (prv) {
                    status = STATUS_SUCCESS;
                    delete prv;
                }
                else {
                    status = STATUS_NOT_FOUND;
                }
            }
        }
        else {
                        RecordValidator *prv =
                new(NonPagedPool, RV_TAG) RecordValidator(pValidate);

            if (prv == NULL) {
                status = STATUS_INSUFFICIENT_RESOURCES;
            }
            else {
                m_RecordValidatorList.Lock();
                m_RecordValidatorList.AddTail(prv);
                m_RecordValidatorList.Unlock();

                status = STATUS_SUCCESS;
            }
        }
    }
    else if (IsEqualUuid(pInterfaceType, &GUID_BTHDDI_SDP_PARSE_INTERFACE)) {
        PBTHDDI_SDP_PARSE_INTERFACE pParse = (PBTHDDI_SDP_PARSE_INTERFACE)
            stack->Parameters.QueryInterface.Interface;

        if (pParse->Interface.Size != sizeof(*pParse) ||
            pParse->Interface.Version < 1) {
            status = STATUS_INVALID_PARAMETER;
        }
        else {
            status = STATUS_SUCCESS;

            pParse->SdpValidateStream = SdpDatabase::ValidateStream;
            pParse->SdpWalkStream = SdpWalkStream;

            pParse->SdpConvertStreamToTree = pSdpTreeFromStream;
            pParse->SdpConvertTreeToStream = SdpStreamFromTree;

            pParse->SdpByteSwapUuid128 = SdpByteSwapUuid128;
            pParse->SdpByteSwapUint128 = SdpByteSwapUint128;
            pParse->SdpByteSwapUint64 =  SdpByteSwapUint64;

            pParse->SdpRetrieveUuid128 = SdpRetrieveUuid128;
            pParse->SdpRetrieveUint128 = SdpRetrieveUint128;
            pParse->SdpRetrieveUint64 =  SdpRetrieveUint64;

            pParse->SdpFindAttribute =         SdpFindAttributeInStream;
            pParse->SdpFindAttributeSequence = SdpFindAttributeSequenceInStream;
            pParse->SdpFindAttributeInTree =   SdpFindAttributeInTree;
        }
    }
    else if (IsEqualUuid(pInterfaceType, &GUID_BTHDDI_SDP_NODE_INTERFACE)) {
        PBTHDDI_SDP_NODE_INTERFACE pNode = (PBTHDDI_SDP_NODE_INTERFACE)
            stack->Parameters.QueryInterface.Interface;

        if (pNode->Interface.Size != sizeof(*pNode) ||
            pNode->Interface.Version < 1) {
            status = STATUS_INVALID_PARAMETER;
        }
        else {
            pNode->SdpCreateNodeTree = SdpCreateNodeTree;
            pNode->SdpFreeTree = SdpFreeTree;

            pNode->SdpCreateNodeNil = SdpCreateNodeNil;

            pNode->SdpCreateNodeBoolean = SdpCreateNodeBoolean;

            pNode->SdpCreateNodeUint8 = SdpCreateNodeUInt8;
            pNode->SdpCreateNodeUint16 = SdpCreateNodeUInt16;
            pNode->SdpCreateNodeUint32 = SdpCreateNodeUInt32;
            pNode->SdpCreateNodeUint64 = SdpCreateNodeUInt64;
            pNode->SdpCreateNodeUint128 = SdpCreateNodeUInt128;

            pNode->SdpCreateNodeInt8 = SdpCreateNodeInt8;
            pNode->SdpCreateNodeInt16 = SdpCreateNodeInt16;
            pNode->SdpCreateNodeInt32 = SdpCreateNodeInt32;
            pNode->SdpCreateNodeInt64 = SdpCreateNodeInt64;
            pNode->SdpCreateNodeInt128 = SdpCreateNodeInt128;

            pNode->SdpCreateNodeUuid16 = SdpCreateNodeUUID16;
            pNode->SdpCreateNodeUuid32 = SdpCreateNodeUUID32;
            pNode->SdpCreateNodeUuid128 = SdpCreateNodeUUID128;

            pNode->SdpCreateNodeString = SdpCreateNodeString;
            pNode->SdpCreateNodeUrl = SdpCreateNodeUrl;

            pNode->SdpCreateNodeAlternative = SdpCreateNodeAlternative;
            pNode->SdpCreateNodeSequence = SdpCreateNodeSequence;

            pNode->SdpAddAttributeToTree = SdpAddAttributeToTree;
            pNode->SdpAppendNodeToContainerNode = SdpAppendNodeToContainerNode;


            status = STATUS_SUCCESS;
        }
    }
    else if (IsEqualUuid(pInterfaceType, &GUID_BTHDDI_MUX_PROTOCOL_INTERFACE)) {
        PBTH_MUX_PROTOCOL_INTERFACE pMux =  (PBTH_MUX_PROTOCOL_INTERFACE)
            stack->Parameters.QueryInterface.Interface;

        if (pMux->Interface.Size != sizeof(*pMux) ||
            pMux->Interface.Version < 1) {
            status = STATUS_INVALID_PARAMETER;
        }
        else {
            status = AddProtMux(&pMux->Protocol);

            if (NT_SUCCESS(status)) {
                pMux->GetSecurityInfoContext = (PVOID) Globals.pSecDB;
                pMux->GetServiceConnectRequirements =
                    SecurityDatabase::_GetServiceConnectRequirements;
            }
        }
    }

    Irp->IoStatus.Status = status;
    return status;
}


void
SdpDatabase::AddDevice(
    PDEVICE_OBJECT DeviceObject
    )
{
    DeviceLE *ple = new (PagedPool, SDP_TAG) DeviceLE(DeviceObject);
    if (ple) {
    }
}

void
SdpDatabase::RemoveDevice(
    PDEVICE_OBJECT DeviceObject
    )
{
    DeviceLE *ple = NULL;

    m_DeviceList.Lock();

    for (ple = m_DeviceList.GetHead();
         ple != NULL;
         ple = m_DeviceList.GetNext(ple)) {
        if (ple->device == DeviceObject) {
            m_DeviceList.RemoveAt(ple);
            break;
        }
    }

    m_DeviceList.Unlock();

    if (ple) {
        delete ple;
    }
}
#endif // UNDER_CE

#if defined (UNDER_CE)


// Remove all entries associated with a process when it's being terminated.
void SdpDatabase::RemoveRecordsAssociatedWithProcess(HANDLE hDyingProc) {
    ServiceRecord *pRecord = m_ServiceRecordList.GetHead();

    m_ServiceRecordList.Lock();

    while (pRecord) {
         if (hDyingProc == pRecord->hCallerProc) {
             ServiceRecord *pNext = m_ServiceRecordList.GetNext(pRecord);

             m_ServiceRecordList.RemoveAt(pRecord);
             AlterDatabaseState();
             delete pRecord;

             pRecord = pNext;
         }
         else
             pRecord = m_ServiceRecordList.GetNext(pRecord);
    }

    m_ServiceRecordList.Unlock();
}
#endif

⌨️ 快捷键说明

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