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

📄 upnphost.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++


File Name:

    upnphost.cpp

Abstract:

This file implements the UPnP Registrar coclass

Author: GeorgeJ

Created: Nov 2000

--*/

#include "upnphostp.h"
#include "upnpmem.h"
#include "auto_xxx.hxx"
// combook.cpp should be included in this file only
#include "combook.cpp"

#define ttidRegistrar 1

HINSTANCE g_hMod;   // Dll module handle

// map CLSID to GetClassObject/UpdateRegistry routine
BEGIN_COCLASS_TABLE(ClassTable)
    IMPLEMENTS_COCLASS(UPnPRegistrar)
END_COCLASS_TABLE()


// implement ModuleAddRef/ModuleRelease/ModuleIsStopping/ModuleIsIdle
IMPLEMENT_DLL_MODULE_ROUTINES()

// implement DllGetClassObject/DllCanUnloadNow/Dll[Un]RegisterServer
IMPLEMENT_DLL_ENTRY_POINTS(g_hMod, ClassTable, 0, FALSE)


#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("UPNPHOST"), {
    TEXT("Misc"), TEXT("Registrar"), TEXT("Automation proxy"), TEXT("Events"),
    TEXT(""),TEXT(""),TEXT(""),TEXT(""),
    TEXT(""),TEXT("Control"),TEXT(""),TEXT(""),
    TEXT(""),TEXT(""),TEXT("Trace"),TEXT("Error") },
    0x00008000
};
#endif

extern "C"
BOOL
WINAPI
DllMain(IN PVOID DllHandle,
        IN ULONG Reason,
        IN PVOID Context OPTIONAL)
{
    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:

        if(!UpnpHeapCreate())
            return FALSE;

        DisableThreadLibraryCalls((HINSTANCE)DllHandle);
        
        DEBUGREGISTER((HMODULE)DllHandle);
        g_hMod = (HINSTANCE)DllHandle; 

        break; 


    case DLL_PROCESS_DETACH:

        UpnpHeapDestroy();
        break;

    }
    return TRUE;
}

//+---------------------------------------------------------------------------
//
//  Function:   AddDevice
//
//  Purpose:    Create and publish the UPnP device tree.
//              Register for callbacks from the service layer.
//              The device has a locally unique name specified
//              by member bstrDeviceId
//
//  Arguments:
//      pszXMLDesc [in] XML device description template
//
//  Returns:
//      HRESULT
//

HRESULT
DeviceProxy::AddDevice(LPWSTR pszXMLDesc)
{
    UPNPDEVICEINFO devInfo;
    BOOL fRet;
    devInfo.cbStruct = sizeof(devInfo);
    devInfo.pszDeviceDescription = pszXMLDesc;
    devInfo.pszDeviceName = m_bstrDeviceId;
    // if the UDN is not NULL, it is assumed to be a UUID
    devInfo.pszUDN = m_bstrUDN;
    devInfo.cachecontrol = m_nLifeTime;
    // all callbacks get a pointer to the DeviceProxy instance
    // as the 2nd Parameter
    devInfo.pvUserDevContext = this;
    devInfo.pfCallback = DevCallback;

    fRet = UpnpAddDevice(&devInfo);
    if (fRet)
    {
        // send out the SSDP announcements
        fRet = UpnpPublishDevice(m_bstrDeviceId);
    }
    if (!fRet)
    {
        return HrFromLastWin32Error();
    }
    return S_OK;
}

//+---------------------------------------------------------------------------
//
//  Function:   RemoveDevice
//
//  Purpose:    Unpublish and unregister the device tree.
//
//  Arguments:
//
//  Returns:
//      HRESULT
//
HRESULT
DeviceProxy::RemoveDevice()
{
    BOOL fRet;
    // no need to explicitly call Unpublish
    fRet = UpnpRemoveDevice(m_bstrDeviceId);
    if (!fRet)
        return HrFromLastWin32Error();
    return S_OK;
}

//+---------------------------------------------------------------------------
//
//  Function:  DevCallback (static method) 
//
//  Purpose:    UPNPCALLBACK prototype that is invoked by the
//              device hosting layer when interesting events
//              occur. In particular, the callback is invoked when
//              control requests are received from remote control points.
//
//  Arguments:
//      callbackId [in] specifies the type of callback event
//      pvUserContext [in] DeviceProxy pointer
//      pvSvcParam [in] depends on callbackId
//
//  Returns:
//      TRUE if success; FALSE if something bad happens
//
DWORD DeviceProxy::DevCallback( 
        UPNPCB_ID callbackId, 
        PVOID pvUserContext,    // app context (from UPNPDEVICEINFO)
        PVOID pvSvcParam)   // depends on CALLBACKID
{
    DeviceProxy *pDevProxy = (DeviceProxy *)pvUserContext;
    switch (callbackId)
    {
        case UPNPCB_INIT:
            return pDevProxy->InitCallback();
            break;
        case UPNPCB_SUBSCRIBING:
            return pDevProxy->SubscribeCallback((UPNPSUBSCRIPTION*)pvSvcParam);
            break;
        case UPNPCB_CONTROL:
            return pDevProxy->ControlCallback((UPNPSERVICECONTROL*)pvSvcParam);
            break;
        case UPNPCB_SHUTDOWN:
            return pDevProxy->ShutdownCallback();
            break;
    }
    return TRUE;
}

//+---------------------------------------------------------------------------
//
//  Method: FindDevProxyByName  
//
//  Purpose:    Locate the named device proxy in the registrar
//              list and return a pointer
//
//  Arguments:
//      pszDevId [in] local name for device tree
//
//  Returns:
//      NULL if the object is not found, else pointer to the DeviceProxy
//
DeviceProxy *
UPnPRegistrar::FindDevProxyByName(PCWSTR pszDevId)
{
    LIST_ENTRY *pLink;
    for (pLink = m_DevProxyList.Flink; pLink != &m_DevProxyList; pLink = pLink->Flink)
    {
        DeviceProxy *pDev;
        pDev = CONTAINING_RECORD(pLink, DeviceProxy, m_link);
        if (wcscmp(pszDevId, pDev->Name()) == 0)
            return pDev;
    }
    return NULL;
}

//+---------------------------------------------------------------------------
//
//  Function:   HrCreateDeviceIdentifier
//
//  Purpose:    Generate a Unique Device Identifier string.
//              uses SysAllocString for memory.
//              The identifier is a 64 bit mini-GUID.
//
//  Arguments:
//      pbstrDevId [out] BSTR UDN (without the uuid: prefix)
//
//  Returns:
//      HRESULT
//
HRESULT
UPnPRegistrar::HrCreateDeviceIdentifier(BSTR *pbstrDevId)
{
    WCHAR wsz[64];
    LONGLONG uuid64 = GenerateUUID64();
    *pbstrDevId = NULL;
    // we need a device Id that is unique and a valid filename 
    // so no illegal characters like ':'
    wsprintfW(wsz, L"%04x%04x-%04x-%04x-0000-000000000000", (WORD)uuid64, *((WORD*)&uuid64 + 1), *((WORD*)&uuid64 + 2), *((WORD*)&uuid64 + 3));

    if (*pbstrDevId = SysAllocString(wsz))
        return S_OK;
    else
        return E_OUTOFMEMORY;
}

//+---------------------------------------------------------------------------
//
//  Function:  IUPnPRegistrar::RegisterRunningDevice 
//
//  Purpose:    Publish an already instantiated UPnP device tree.
//              See public docs for more info
//
//  Arguments:
//      bstrXMLDesc [in] XML device description template
//      punkDeviceControl [in] IUPnPDeviceControl interface of the object
//      bstrInitString [in] optional string to be passed back to object on init
//      bstrResourcePath [in] NULL - not used for WinCE. The resources should
//                      be under the \windows\upnp directory.
//      nLifeTime [in] lifetime in seconds. Maybe 0 for system default
//      pbstrDeviceIdentifier [out] id generated by UPnP service for use in
//                  UnregisterDevice and ReregisterDevice
//  Returns:
//      HRESULT
//
STDMETHODIMP
UPnPRegistrar::RegisterRunningDevice(
        /*[in]*/ BSTR     bstrXMLDesc,
        /*[in]*/ IUnknown * punkDeviceControl,
        /*[in]*/ BSTR     bstrInitString,
        /*[in]*/ BSTR     bstrResourcePath,
        /*[in]*/ long     nLifeTime,
        /*[out, retval]*/ BSTR * pbstrDeviceIdentifier)
{
    HRESULT hr = S_OK;
    BSTR bstrDeviceId = NULL;

    *pbstrDeviceIdentifier = NULL;
    // construct pbstrDeviceIdentifier
    hr = HrCreateDeviceIdentifier( &bstrDeviceId);
    if (SUCCEEDED(hr))
    {
        // add device
        hr = ReregisterRunningDevice(
            bstrDeviceId,
            bstrXMLDesc,
            punkDeviceControl,
            bstrInitString,
            bstrResourcePath,
            nLifeTime
            );
        if (SUCCEEDED(hr))
        {
            *pbstrDeviceIdentifier = bstrDeviceId;
        }
        else
        {
            SysFreeString(bstrDeviceId);
        }
    }

    return hr;
}

static const int MaxInstances = 30;

//+---------------------------------------------------------------------------
//
//  Function:  IUPnPRegistrar::RegisterDevice 
//
//  Purpose:    Publish UPnP device tree with delayed instantiaton of the
//              device implementation
//              See public docs for more info
//
//  Arguments:
//      pszXMLDesc [in] XML device description template
//      bstrProgIDDeviceControlClass [in] CLSID of COM device implementation
//      bstrInitString [in] optional string to be passed back to object on init
//      bstrContainerId [in] NULL - not used on WinCE
//      bstrResourcePath [in] NULL - not used for WinCE. The resources should
//                      be under the \windows\upnp directory.
//      nLifeTime [in] lifetime in seconds. Maybe 0 for system default
//      pbstrDeviceIdentifier [out] id generated by UPnP service for use in
//                  UnregisterDevice and ReregisterDevice
//  Returns:
//      HRESULT
//
STDMETHODIMP UPnPRegistrar::RegisterDevice(
    /*[in]*/ BSTR     bstrXMLDesc,
    /*[in]*/ BSTR     bstrProgIDDeviceControlClass,
    /*[in]*/ BSTR     bstrInitString,
    /*[in]*/ BSTR     bstrContainerId,
    /*[in]*/ BSTR     bstrResourcePath,
    /*[in]*/ long     nLifeTime,
    /*[out, retval]*/ BSTR * pbstrDeviceIdentifier)
{
    HRESULT hr = E_FAIL;
    BSTR bstrDeviceId = NULL;

    *pbstrDeviceIdentifier = NULL;

    if (bstrXMLDesc == NULL
        || bstrProgIDDeviceControlClass == NULL
        || pbstrDeviceIdentifier == NULL)
    {
        return E_INVALIDARG;
    }

    // construct pbstrDeviceIdentifier
    hr = HrCreateDeviceIdentifier( &bstrDeviceId);
    if (SUCCEEDED(hr))
    {
        hr = ReregisterDevice(
                bstrDeviceId,
                bstrXMLDesc,
                bstrProgIDDeviceControlClass,
                bstrInitString,
                bstrContainerId,
                bstrResourcePath,
                nLifeTime);
        if (SUCCEEDED(hr))
        {
            *pbstrDeviceIdentifier = bstrDeviceId;
        }
        else
            SysFreeString(bstrDeviceId);

    }
    return hr;
}

static const WCHAR c_szuuidprefix[] = L"uuid:";

//+---------------------------------------------------------------------------
//
//  Function:   
//
//  Purpose:    Create and publish the UPnP device tree.
//
//  Arguments:
//      pszXMLDesc [in] XML device description template
//
//  Returns:
//      HRESULT
//
STDMETHODIMP UPnPRegistrar::ReregisterRunningDevice(
    /*[in]*/ BSTR     bstrDeviceIdentifier,
    /*[in]*/ BSTR     bstrXMLDesc,
    /*[in]*/ IUnknown * punkDeviceControl,
    /*[in]*/ BSTR     bstrInitString,
    /*[in]*/ BSTR     bstrResourcePath,
    /*[in]*/ long     nLifeTime)
{
    HRESULT hr = S_OK;
    DeviceProxy *pDevProxy;
    WCHAR *pszUDN;

    pDevProxy = FindDevProxyByName(bstrDeviceIdentifier);
    if (pDevProxy)
    {
        return E_FAIL;  // TODO: proper error
    }
    // construct UDN as "uuid:<bstrDeviceIdentifier>"
    pszUDN = new WCHAR[wcslen(bstrDeviceIdentifier) + celems(c_szuuidprefix)];
    if (!pszUDN)
    {
        return E_OUTOFMEMORY;
    }
    wcscpy(pszUDN, c_szuuidprefix);
    wcscat(pszUDN, bstrDeviceIdentifier);

    pDevProxy = new DeviceProxy(
                    bstrDeviceIdentifier,
                    bstrInitString,
                    bstrResourcePath,
                    bstrXMLDesc,
                    nLifeTime,
                    punkDeviceControl,
                    pszUDN
                    );
    if (pDevProxy)
    {
        hr = pDevProxy->AddDevice(bstrXMLDesc);
        if (SUCCEEDED(hr))
        {
            pDevProxy->AddToList(&m_DevProxyList);
        }
        else
            delete pDevProxy;
    }
    else
        hr = E_OUTOFMEMORY;

    delete[] pszUDN;

    return hr;
}

#define __OPT_PLAT_FLAG (defined (ARMV4T))
#define __OPT_VER_OFF
#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::ReregisterDevice(
    /*[in]*/ BSTR     bstrDeviceIdentifier,
    /*[in]*/ BSTR     bstrXMLDesc,
    /*[in]*/ BSTR     bstrProgIDDeviceControlClass,
    /*[in]*/ BSTR     bstrInitString,
    /*[in]*/ BSTR     bstrContainerId,
    /*[in]*/ BSTR     bstrResourcePath,
    /*[in]*/ long     nLifeTime)
{
    HRESULT hr = E_FAIL;
    HANDLE hUPnPHostingEvent;


    TraceTag(ttidRegistrar, "UPnPRegistrar::ReregisterDevice");
    if ( bstrDeviceIdentifier == NULL 
        || bstrXMLDesc == NULL
        || bstrProgIDDeviceControlClass == NULL
        )
    {
        return E_INVALIDARG;
    }
    // make sure the hosting service is around
    hUPnPHostingEvent = CreateEvent(NULL,FALSE,FALSE,UPNPLOADEREVENTNAME);
    if (hUPnPHostingEvent == NULL)

⌨️ 快捷键说明

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