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

📄 upnphost.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        return E_FAIL;
    // the service is supposed to create the named event
    if (GetLastError() != ERROR_ALREADY_EXISTS)
    {
        CloseHandle(hUPnPHostingEvent);
        return HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_FOUND);
    }


    RegEntry upnpDevicesKey(UPNPDEVICESKEY);
    if (upnpDevicesKey.Success())
    {
        RegEntry upnpDeviceKey(bstrDeviceIdentifier, upnpDevicesKey.GetKey());
        
        if (upnpDeviceKey.Success())
        {
            if ((bstrInitString && (hr = upnpDeviceKey.SetValue(L"InitString",bstrInitString)))
                ||(bstrProgIDDeviceControlClass && (hr = upnpDeviceKey.SetValue(L"ProgId",bstrProgIDDeviceControlClass)))
                || (bstrResourcePath && (hr = upnpDeviceKey.SetValue(L"ResourcePath",bstrResourcePath)))
                || (hr = upnpDeviceKey.SetValue(L"XMLDesc",bstrXMLDesc)) // is this too big for the registry?
                || (hr = upnpDeviceKey.SetValue(L"State", UPNPREG_STARTING))
                || (hr = upnpDeviceKey.SetValue(L"UDN", bstrDeviceIdentifier))
                || (hr = upnpDeviceKey.SetValue(L"LifeTime", nLifeTime))) 
            {
                hr = HRESULT_FROM_WIN32(hr);
                upnpDeviceKey.DeleteKey();
                RegDeleteKey(upnpDevicesKey.GetKey(),bstrDeviceIdentifier);
            }
        }
    }
    if (SUCCEEDED(hr))
    {
        // signal the hosting process
        SetEvent(hUPnPHostingEvent);
    }
    CloseHandle(hUPnPHostingEvent);
    return hr;
}

#define __OPT_PLAT_FLAG (defined (ARMV4T))
#define __OPT_VER_RESTORE
#define __OPT_BUGNUMSTRING  "26316"
#include <optimizer.h>



//+---------------------------------------------------------------------------
//
//  Function:   
//
//  Purpose:    Create and publish the UPnP device tree.
//
//  Arguments:
//      pszXMLDesc [in] XML device description template
//
//  Returns:
//      HRESULT
//
STDMETHODIMP UPnPRegistrar::UnregisterDevice(
    /*[in]*/ BSTR     bstrDeviceIdentifier,
    /*[in]*/ BOOL     fPermanent)
{
    TraceTag(ttidRegistrar, "UPnPRegistrar::UnregisterDevice");
    HRESULT hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
    HANDLE hUPnPHostingEvent = NULL;

    if (bstrDeviceIdentifier == NULL || *bstrDeviceIdentifier == 0)
    {
        return E_INVALIDARG;
    }
    RegEntry upnpDevicesKey(UPNPDEVICESKEY);
    if (upnpDevicesKey.Success())
    {
        if (fPermanent)
        {
            hr = RegDeleteKey(upnpDevicesKey.GetKey(),bstrDeviceIdentifier);
        }
        else
        {
            RegEntry upnpDeviceKey(bstrDeviceIdentifier, upnpDevicesKey.GetKey(), FALSE); // open existing device key
            hr = upnpDeviceKey.SetValue(UPNPSTATEVALUE,UPNPREG_DISABLED);
            hr = HRESULT_FROM_WIN32(hr);
        }
        if (SUCCEEDED(hr))
        {
            // this appears to be  registered device. Need to signal the hosting process if its running
            hUPnPHostingEvent = CreateEvent(NULL,FALSE,FALSE,UPNPLOADEREVENTNAME);
            if (hUPnPHostingEvent && GetLastError() != ERROR_ALREADY_EXISTS)
            {
                // the hosting process is not around
                CloseHandle(hUPnPHostingEvent);
                hUPnPHostingEvent = NULL;
            }
        }

    }
    if (!UpnpRemoveDevice(bstrDeviceIdentifier) && hr != 0)
    {
        // return failure if we were not able to remove the device and it was not in the registry
        hr = HRESULT_FROM_WIN32(GetLastError());
    }
    else
        hr = S_OK;

    if (hUPnPHostingEvent)
    {
        // signal the hosting process. Otherwise it may not get to know that the device has been unregistered
        SetEvent(hUPnPHostingEvent);
        CloseHandle(hUPnPHostingEvent);
    }

    return hr;
}



//+---------------------------------------------------------------------------
//
//  Function:   
//
//  Purpose:    Create and publish the UPnP device tree.
//
//  Arguments:
//      pszXMLDesc [in] XML device description template
//
//  Returns:
//      HRESULT
//
STDMETHODIMP UPnPRegistrar::GetUniqueDeviceName(
    /*[in]*/          BSTR   bstrDeviceIdentifier,
    /*[in]*/          BSTR   bstrTemplateUDN,
    /*[out, retval]*/ BSTR * pbstrUDN)
{
    HRESULT hr = S_OK;
    WCHAR szUDN[128];
    DWORD cchUDN = sizeof(szUDN)/sizeof(szUDN[0]);
    if (!UpnpGetUDN(bstrDeviceIdentifier, bstrTemplateUDN, szUDN, &cchUDN))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }
    else
    {
        *pbstrUDN = SysAllocString(szUDN);
        if (!*pbstrUDN)
            hr = E_OUTOFMEMORY;
    }

    return hr;
}

STDMETHODIMP UPnPRegistrar::RegisterDeviceProvider(
    /*[in]*/ BSTR     bstrProviderName,
    /*[in]*/ BSTR     bstrProgIDProviderClass,
    /*[in]*/ BSTR     bstrInitString,
    /*[in]*/ BSTR     bstrContainerId)
{
    return E_NOTIMPL;
}

STDMETHODIMP UPnPRegistrar::UnregisterDeviceProvider(
    /*[in]*/ BSTR     bstrProviderName)
{
    return E_NOTIMPL;
}


//
//  DeviceProxy implementation
//


//+---------------------------------------------------------------------------
//
//  Function:   FreeControlRequest
//
//  Purpose:    Frees resources used by the fields of a UPNP_CONTROL_REQUEST
//              structure
//
//  Arguments:
//      pucr [in] Address of the structure to cleanup
//
//  Returns:
//      (none)
//    This function just frees the resources used by the fields within
//    the passed in structure. It does not free the memory used by the
//    structure itself.
//
static VOID
FreeControlRequest(
    IN UPNP_CONTROL_REQUEST    * pucr)
{
    if (pucr->bstrActionName)
    {
        SysFreeString(pucr->bstrActionName);
        pucr->bstrActionName = NULL;
    }

    if (pucr->rgvarInputArgs)
    {
        for (DWORD i = 0; i < pucr->cInputArgs; i++)
        {
            VariantClear(&pucr->rgvarInputArgs[i]);
        }

        delete [] pucr->rgvarInputArgs;
        pucr->rgvarInputArgs = NULL;
        pucr->cInputArgs = 0;
    }
}



//+---------------------------------------------------------------------------
//
//  Function:   FormatControlRequest
//
//  Purpose:    Copy the action name, parameter names and values from the
//              UPNPSERVICECONTROL struct to the UPNP_CONTROL_REQUEST struct
//              
//              The existence of two different types is possibly avoidable
//              but one meshes with the COM world, and one does not.
//
//  Arguments:
//      pSvcCtl [in] pointer to the populated UPNPSERVICECONTROL struct
//      pucreq  [out] pointer to the empty UPNP_CONTROL_REQUEST struct
//
//  Returns:
//      TRUE if the fields were copied successully to pucreq
//
static
BOOL
FormatControlRequest(UPNPSERVICECONTROL *pSvcCtl, UPNP_CONTROL_REQUEST *pucreq)
{
    BOOL fRet = TRUE;
    UINT i;
    ZeroMemory(pucreq, sizeof(*pucreq));
    pucreq->bstrActionName = SysAllocString(pSvcCtl->pszAction);
    if (pSvcCtl->cInArgs)
    {
        pucreq->rgvarInputArgs = new VARIANT[pSvcCtl->cInArgs];
        if (pucreq->rgvarInputArgs)
        {
            pucreq->cInputArgs = pSvcCtl->cInArgs;
            for (i=0; i< pSvcCtl->cInArgs; i++)
            {
                V_BSTR(&pucreq->rgvarInputArgs[i]) = SysAllocString(pSvcCtl->pInArgs[i].pszValue);
                if (!V_BSTR(&pucreq->rgvarInputArgs[i]))
                {
                    fRet = FALSE;   // is it ok to have a NULL value?
                    break;
                }
                pucreq->rgvarInputArgs[i].vt = VT_BSTR;
            }

        }
        else
            fRet = FALSE;
    }
    if (!fRet)
    {
        // free any strings we allocated
        FreeControlRequest(pucreq); 
    }
    return fRet;
}



//+---------------------------------------------------------------------------
//
//  Function:   FreeControlResponse
//
//  Purpose:    Frees resources used by the fields of a UPNP_CONTROL_RESPONSE
//              structure
//
//  Arguments:
//      pucr [in] Address of the structure to cleanup
//
//  Returns:
//      (none)
//
//  Notes:
//    This function just frees the resources used by the fields within
//    the passed in structure. It does not free the memory used by the
//    structure itself.
//
static VOID
FreeControlResponse(
    IN UPNP_CONTROL_RESPONSE    * pucresp)
{
    if (pucresp->bstrActionName)
    {
        SysFreeString(pucresp->bstrActionName);
        pucresp->bstrActionName = NULL;
    }

    UPNP_CONTROL_RESPONSE_DATA * pucrd = &pucresp->ucrData;

    if (pucresp->fSucceeded)
    {
        if (pucrd->Success.rgvarOutputArgs)
        {
            for (DWORD i = 0; i < pucrd->Success.cOutputArgs; i++)
            {
                VariantClear(&pucrd->Success.rgvarOutputArgs[i]);
            }

            CoTaskMemFree(pucrd->Success.rgvarOutputArgs);
            pucrd->Success.rgvarOutputArgs = NULL;
            pucrd->Success.cOutputArgs = 0;
        }
    }
    else
    {
        if (pucrd->Fault.bstrFaultCode)
        {
            SysFreeString(pucrd->Fault.bstrFaultCode);
            pucrd->Fault.bstrFaultCode = NULL;
        }

        if (pucrd->Fault.bstrFaultString)
        {
            SysFreeString(pucrd->Fault.bstrFaultString);
            pucrd->Fault.bstrFaultString = NULL;
        }

        if (pucrd->Fault.bstrUPnPErrorCode)
        {
            SysFreeString(pucrd->Fault.bstrUPnPErrorCode);
            pucrd->Fault.bstrUPnPErrorCode = NULL;
        }

        if (pucrd->Fault.bstrUPnPErrorString)
        {
            SysFreeString(pucrd->Fault.bstrUPnPErrorString);
            pucrd->Fault.bstrUPnPErrorString = NULL;
        }
    }
}


//+---------------------------------------------------------------------------
//
//  Function:   GetServiceProxy
//
//  Purpose:    Locate the ServiceProxy object by serviceId. If it does not exist
//              attempt to create and initialize one and add it to the list.
//
//
//  Arguments:
//      pszServiceId [in] serviceId string
//
//  Returns:
//      pointer to the ServiceProxy object or NULL if failure.
//      pointer is not AddRef'ed.
//
ServiceProxy *
DeviceProxy::GetServiceProxy(LPCWSTR pszUDN, LPCWSTR pszServiceId)
{
    ServiceProxy    *pSvc;
    HRESULT         hr;
    IDispatch       *pISO;

    for (pSvc=m_pServices;pSvc; pSvc = pSvc->m_pNext)
    {
        if (wcscmp(pszServiceId, pSvc->m_bstrSid) == 0 && wcscmp(pszUDN, pSvc->m_bstrUDN) == 0)
            break;
    }

    if (!pSvc)
    {
        // this may be the first time, so create one
        if (m_pDeviceControl)
        {
            ce::auto_bstr bstrUDN, bstrServiceId;

            bstrUDN = SysAllocString(pszUDN);
            bstrServiceId = SysAllocString(pszServiceId);

            hr = m_pDeviceControl->GetServiceObject(bstrUDN, bstrServiceId, &pISO);

            if (SUCCEEDED(hr))
            {
                WCHAR szSCPDPath[MAX_PATH];

                // get the SCPD
                UpnpGetSCPDPath(m_bstrDeviceId, pszUDN, pszServiceId, szSCPDPath, celems(szSCPDPath));

                pSvc = new ServiceProxy(this);

                if (pSvc)
                {
                    pSvc->AddRef();     // set the ref count to 1

                    hr = pSvc->Initialize(pszUDN, pszServiceId, szSCPDPath, pISO);
                    if (SUCCEEDED(hr))
                    {
                        // add to service list
                        pSvc->m_pNext = m_pServices;
                        m_pServices = pSvc;
                        // submit the initial state variables
                        pSvc->OnStateChanged(0,NULL);   // 0,NULL => all variables
                    }
                    else
                    {
                        pSvc->Release();    // this should delete the object
                        pSvc = NULL;
                    }
                }

                pISO->Release();
            }
        }
    }
    return pSvc;
}

//+---------------------------------------------------------------------------
//
//  Method:   DeviceProxy::SubscribeCallback
//
//  Purpose:    Invoked when a remote subscription request is received.
//
//  Arguments:
//      UPNPSUBSCRIPTION *pUPnPSubscription
//
//  Returns:
//      TRUE if the subscription is accepted
//
BOOL
DeviceProxy::SubscribeCallback(UPNPSUBSCRIPTION *pUPnPSubscription)
{
    ServiceProxy *pServiceProxy;
    // We need to have a pointer to the implementation object by now
    if (!m_pDeviceControl)
    {
        return FALSE;
    }

    // Find the service proxy by serviceId 
    // create if necessary
    pServiceProxy = GetServiceProxy(pUPnPSubscription->pszUDN, pUPnPSubscription->pszSID);

    if (!pServiceProxy)
    {
        TraceTag(ttidError, "SubscribeCallback: No service proxy for Service ID %S\n", pUPnPSubscription->pszSID);
        return FALSE;   
    }

    pServiceProxy->UpdateEventedVariables(FALSE, 0, NULL);  // FALSE -> just update, don't send event; 0, NULL -> all evented variables
    
    return TRUE;
}

//+---------------------------------------------------------------------------
//
//  Function:   ControlCallback
//
//  Purpose:    Invoked when a remote control request is received
//
//  Arguments:
//      pszXMLDesc [in] XML device description template
//
//  Returns:
//      HRESULT
//
BOOL
DeviceProxy::ControlCallback(UPNPSERVICECONTROL *pSvcCtl)
{
    HRESULT hr;
    BOOL fRet = FALSE;
    UPNP_CONTROL_REQUEST ucreq;
    UPNP_CONTROL_RESPONSE ucresp;
    ServiceProxy *pServiceProxy;
    TraceTag(ttidRegistrar, "DeviceProxy::ControlRequest\n");
    Assert(pSvcCtl->pszSID);
    Assert(m_pDeviceControl);
    // We need to have a pointer to the implementation object by now
    if (!m_pDeviceControl)
    {
        return FALSE;
    }

    // Find the service proxy by serviceId 
    // create if necessary
    pServiceProxy = GetServiceProxy(pSvcCtl->pszUDN, pSvcCtl->pszSID);
    if (!pServiceProxy)
    {
        TraceTag(ttidError, "ControlCallback: No service proxy for Service ID %S\n", pSvcCtl->pszSID);
        return FALSE;   
    }

⌨️ 快捷键说明

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