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

📄 devtree.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }
    // recurse down
    if (fRet && m_pFirstChildDev)
        fRet = m_pFirstChildDev->SsdpRegister(dwLifeTime, pszDescURL);

    // recurse right
    if (fRet && m_pNextDev)
        fRet = m_pNextDev->SsdpRegister(dwLifeTime, pszDescURL);

    if (!fRet)
    {
        SsdpUnregister();
    }
    return fRet;
}

BOOL HostedDevice::SsdpUnregister(void)
{
    BOOL fRet = TRUE;
    HostedService *pService;
    if (m_pFirstChildDev)
        fRet &= m_pFirstChildDev->SsdpUnregister();

    if (m_pNextDev)
        fRet &= m_pNextDev->SsdpUnregister();

    if (VALIDSSDPH(m_hSSDPUDN))
        fRet &= DeregisterUpnpService(m_hSSDPUDN, TRUE);
    m_hSSDPUDN = INVALID_HANDLE_VALUE;
    
    if (VALIDSSDPH(m_hSSDPDevType))
        fRet &= DeregisterUpnpService(m_hSSDPDevType, TRUE);
    m_hSSDPDevType = INVALID_HANDLE_VALUE;

    for (pService=m_pFirstService;pService;pService=pService->NextService())
    {
        fRet &= pService->SsdpUnregister();
    }
    
    return fRet;
    
}

BOOL
HostedDeviceTree::DoDeviceCallback(ControlRequest *pControlReq, UPNPCB_ID id, PCWSTR pszUDN, PCWSTR pszServiceId, PCWSTR pszReqXML)
{
    BOOL fRet = FALSE;
    DispatchGate *pGate = NULL;

    TraceTag(ttidControl, "%s: [%08x] Perform Callback [%08x]\n", __FUNCTION__, this, m_pfCallback);

    if (!m_pfCallback)
        return FALSE;

    pGate = DispatchGate::FindDispatchGateForProc(m_hOwnerProc);
    if (!pGate)
        return FALSE;

    fRet = pGate->EnterGate();
    if (!fRet)
    {
        pGate->DecRef();     // ensure that the gate reference is released
        return FALSE;           // we are unable to initiate a callback
    }

    fRet = FALSE;
    UpnpInvokeRequestContainer_t requestContainer;

    __try {

            if(requestContainer.CreateUpnpInvokeRequest(
                                                    pszReqXML, 
                                                    pszServiceId, 
                                                    pszUDN, 
                                                    (DWORD) m_pszName, 
                                                    (DWORD) m_pvCallbackContext, 
                                                    id) == FALSE) {
                    TraceTag(ttidError,"%s: [%08x] Exception packing invoke request in DoDeviceCallback id= %d", __FUNCTION__, this, id);
                    goto Finish;
                }

            m_pCurControlReq = pControlReq;
            TraceTag(ttidControl, "%s: [%08x] Setting Current Control Request [%08x]\n", __FUNCTION__, this, m_pCurControlReq);
            fRet = pGate->DoCallback(requestContainer); // this will block
            m_pCurControlReq = NULL;
            TraceTag(ttidControl, "%s: [%08x] Unsetting Current Control Request [%08x]\n", __FUNCTION__, this, m_pCurControlReq);

    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        TraceTag(ttidError,"Exception in DoDeviceCallback id= %d", id);
    }

Finish:

    pGate->LeaveGate();
    pGate->DecRef();

    return fRet;
}


BOOL
HostedDeviceTree::Control(ControlRequest *pCReq)
{
    HostedService *pService;
    BOOL fRet = FALSE;
    TraceTag(ttidControl, "%s: [%08x] Control Request for UDN[%S]\n", __FUNCTION__, this, m_pszName);
    TraceTag(ttidControl, "%s: [%08x] Control Request for ServiceID[%S]\n", __FUNCTION__, this, pCReq->ServiceId());


    Lock();

    Assert(m_pRootDevice);
    pService = m_pRootDevice->FindService(pCReq->UDN(), pCReq->ServiceId());
    TraceTag(ttidControl, "%s: [%08x] Control Request Service [%08x]\n", __FUNCTION__, this, pService);

    if (m_state >= DevTreePublished && pService)
    {
        // assume its okay to control
        if (m_state < DevTreeRunning)
        {
            // the device is being invoked for the first time
            m_state = DevTreeRunning;

            // Send the startup notification to the device implementation
            TraceTag(ttidControl, "%s: [%08x] UPNPCB_INIT\n", __FUNCTION__, this);

            Unlock();
            fRet = DoDeviceCallback(NULL, UPNPCB_INIT, NULL, NULL, NULL);
            Lock();

            if (!fRet && m_state > DevTreePublished)
            {
                m_state = DevTreePublished; // uh-oh Init failed
                TraceTag(ttidControl, "%s: [%08x] failed init\n", __FUNCTION__, this);
            }
        }

        // since we may have changed state in the previous Unlock(), check again
        if (m_state >= DevTreeRunning)
        {
            TraceTag(ttidControl, "%s: [%08x] UPNPCB_CONTROL\n", __FUNCTION__, this);

            Unlock();
            fRet = DoDeviceCallback(pCReq, UPNPCB_CONTROL, pCReq->UDN(), pCReq->ServiceId(), pCReq->RequestXML());
            Lock();
        }
    }

    Unlock();

    TraceTag(ttidControl, "%s: [%08x] Completed Control Request [%S]\n", __FUNCTION__, this, fRet ? L"TRUE" : L"FALSE");
    return fRet;
}

BOOL
HostedDeviceTree::Subscribe(PCWSTR szUDN, PCWSTR pszServiceId)
{
    HostedService *pService;
    BOOL fRet = FALSE;

    TraceTag(ttidTrace, "%s: [%08x] Subscribing UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);

    Lock();

    Assert(m_pRootDevice);
    pService = m_pRootDevice->FindService(szUDN, pszServiceId);
    
    if (m_state >= DevTreePublished && pService)
    {
        // assume its okay to subscribe
        if (m_state < DevTreeRunning)
        {
            // the device is being invoked for the first time
            m_state = DevTreeRunning;

            // Send the startup notification to the device implementation

            Unlock();
            fRet = DoDeviceCallback(NULL, UPNPCB_INIT, NULL, NULL, NULL);
            Lock();

            if (!fRet && m_state > DevTreePublished)
                m_state = DevTreePublished; // uh-oh Init failed
        }

        // since we may have changed state in the previous Unlock(), check again
        if (m_state >= DevTreeRunning)
        {
            Unlock();
            fRet = DoDeviceCallback(NULL, UPNPCB_SUBSCRIBING, szUDN, pszServiceId, NULL);
            Lock();
        }
    }

    Unlock();

    TraceTag(ttidTrace, "%s: [%08x] Subscribed UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
    return fRet;
}

BOOL
HostedDeviceTree::Unsubscribe(PCWSTR szUDN, PCWSTR pszServiceId)
{
    TraceTag(ttidTrace, "%s: [%08x] Unsubscribing UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
    DoDeviceCallback(NULL, UPNPCB_UNSUBSCRIBING, szUDN, pszServiceId, NULL);

    TraceTag(ttidTrace, "%s: [%08x] Unsubscribed UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, pszServiceId);
    return TRUE;
}

BOOL
HostedDeviceTree::SetControlResponse(DWORD dwHttpStatus, PCWSTR pszResp)
{
    BOOL fRet = FALSE;

    Lock();

    if (m_pCurControlReq)
        fRet = m_pCurControlReq->SetResponse(dwHttpStatus, pszResp);
    else 
        Assert(false);

    Unlock();
    TraceTag(ttidTrace, "%s: [%08x] Set Control Response [%S]\n", __FUNCTION__, this, fRet ? L"TRUE" : L"FALSE");

    return fRet;
}

static void FreeUPNP_PROPERTY(DWORD nArgs, UPNP_PROPERTY *rgUpnpProps)
{
    DWORD i;
    for (i=0;i<nArgs;i++)
    {
        if(rgUpnpProps[i].szName)
            free(rgUpnpProps[i].szName);

        if(rgUpnpProps[i].szValue)
            free(rgUpnpProps[i].szValue);
    }

    delete [] rgUpnpProps;
}

static UPNP_PROPERTY *CopyUPNPPARAMtoPROPERTY(DWORD nArgs, UPNPPARAM *rgArgs)
{
    UPNP_PROPERTY *rgUpnpProps = new UPNP_PROPERTY [nArgs];
    DWORD i;
    if (rgUpnpProps)
    {
        __try {
        for (i=0;i<nArgs;i++)
        {
            rgUpnpProps[i].szName = _wcsdup(rgArgs[i].pszName);
            rgUpnpProps[i].szValue = _wcsdup(rgArgs[i].pszValue);
            rgUpnpProps[i].dwFlags = 0;
            if (!rgUpnpProps[i].szName || !rgUpnpProps[i].szValue)
                break;
        }
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
        }
        if (i<nArgs)
        {
            FreeUPNP_PROPERTY(i, rgUpnpProps);
            rgUpnpProps = NULL;
        }
    }
    return rgUpnpProps;
}


HostedService::~HostedService()
{
    delete m_pNextService;
    delete m_pszServiceId;
    delete m_pszServiceType;
    delete m_pszSCPDPath;

    if (m_pszaUri)
    {
        if (m_fEventing)
            DeregisterUpnpEventSource(m_pszaUri);
        delete m_pszaUri;
    }
}


BOOL
HostedService::SsdpRegister(DWORD dwLifeTime, PCWSTR pszDescURL, PCWSTR pszUDN )
{
    // publish the service type:
    // 
    m_hSSDPSvc = RegisterSSDPService(dwLifeTime, pszDescURL, pszUDN, m_pszServiceType);

    // Register this service as an event source
    if (VALIDSSDPH(m_hSSDPSvc))
        m_fEventing = RegisterUpnpEventSource(m_pszaUri, 0, NULL);
    

    return (VALIDSSDPH(m_hSSDPSvc) && m_fEventing);
}

BOOL
HostedService::SsdpUnregister()
{
    BOOL fRet = TRUE;
    if (VALIDSSDPH(m_hSSDPSvc))
        fRet = DeregisterUpnpService(m_hSSDPSvc, TRUE);
    m_hSSDPSvc = INVALID_HANDLE_VALUE;
    if (m_fEventing && m_pszaUri)
    {
        DeregisterUpnpEventSource(m_pszaUri);
        m_fEventing = FALSE;
    }
    return fRet;
}

BOOL
HostedService::SubmitPropertyEvent(
    DWORD dwFlags,
    DWORD nArgs,
    UPNPPARAM *rgArgs)
{
    BOOL fRet;
    UPNP_PROPERTY *rgUpnpProps;

    // convert to ascii parameter array, understood by eventing subsystem
    rgUpnpProps = CopyUPNPPARAMtoPROPERTY(nArgs, rgArgs);

    if (!rgUpnpProps)
        return FALSE;
        
    fRet = FALSE;
    if (m_fEventing)
        fRet = SubmitUpnpPropertyEvent(m_pszaUri, dwFlags, nArgs, rgUpnpProps);

    FreeUPNP_PROPERTY(nArgs, rgUpnpProps);

    return fRet;
}


HostedDevice *
HostedDevice::FindDevice(PCWSTR pszUDN)
{
    HostedDevice *pDevice = NULL;
    if (wcscmp(pszUDN, m_pszUDN) == 0)
    {
            return this; 
    }
    // recurse down
    if (m_pFirstChildDev && (pDevice = m_pFirstChildDev->FindDevice(pszUDN)))
        return pDevice;
    // recurse left
    if (m_pNextDev)
        pDevice = m_pNextDev->FindDevice(pszUDN);
    return pDevice;
    
}

HostedDevice *
HostedDevice::FindByOrigUDN(PCWSTR pszTemplateUDN)
{
    HostedDevice *pDevice = NULL;
    if (m_pszOrigUDN && wcscmp(pszTemplateUDN, m_pszOrigUDN) == 0)
    {
        return this; 
    }
    // recurse down
    if (m_pFirstChildDev && (pDevice = m_pFirstChildDev->FindByOrigUDN(pszTemplateUDN)))
        return pDevice;
    // recurse left
    if (m_pNextDev)
        pDevice = m_pNextDev->FindByOrigUDN(pszTemplateUDN);
        
    return pDevice;
    
}


HostedService *
HostedDevice::FindService(PCWSTR pszUDN, PCWSTR pszServiceId)
{
    HostedService *pService = NULL;

    if(0 == wcscmp(pszUDN, m_pszUDN))
        for (pService = m_pFirstService; pService; pService = pService->NextService())
        {
            if (wcscmp(pszServiceId, pService->ServiceId()) == 0)
                return pService;
        }

    // recurse down
    if (m_pFirstChildDev && (pService = m_pFirstChildDev->FindService(pszUDN, pszServiceId)))
        return pService;

    // recurse left
    if (m_pNextDev)
        pService = m_pNextDev->FindService(pszUDN, pszServiceId);

    return pService;
}



⌨️ 快捷键说明

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