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

📄 devtree.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
#include "pch.h"
#pragma hdrstop
#pragma warning (disable : 4509)

BOOL RegisterUpnpServiceImpl(PSSDP_MESSAGE pSsdpMessage, DWORD flags, HANDLE* phService);

#define MAX_STRING 256

//
// string dup utility functions that use new instead of malloc as the allocator
//
PSTR
StrDupWtoA(LPCWSTR pwszSource)
 {
    PSTR psza;
    size_t nBytes;
    if (!pwszSource)
        return NULL;
    nBytes =  wcslen(pwszSource)+1;
    if (psza = new CHAR [nBytes])
        wcstombs(psza,pwszSource,nBytes);
    return psza;
    
}

PWSTR
StrDupAtoW(LPCSTR pszaSource)
{
    size_t nBytes;
    PWSTR pwsz;
    if (!pszaSource)
        return NULL;
    nBytes = strlen(pszaSource)+1;
    if (pwsz = new WCHAR [nBytes])
    {
        mbstowcs(pwsz,pszaSource, nBytes);
    }
    return pwsz;
}

PWSTR
StrDupW(LPCWSTR pwszSource)
{
    PWSTR pwsz;
    size_t nBytes;
    if (!pwszSource)
        return NULL;
    nBytes =  wcslen(pwszSource)+1;
    if (pwsz = new WCHAR [nBytes])
        memcpy(pwsz,pwszSource,nBytes*sizeof(WCHAR));
    return pwsz;
}


PWSTR
CreateUDN(void)
{
    PWSTR pszUDN;
    LONGLONG uuid64 = GenerateUUID64();
    // GUID guid;
    //CeGenerateGUID(&guid);
    pszUDN = new WCHAR [42];
    if (!pszUDN) return NULL;
    
    wsprintfW(pszUDN, L"uuid:%04x%04x-%04x-%04x-0000-000000000000", (WORD)uuid64, *((WORD*)&uuid64 + 1), *((WORD*)&uuid64 + 2), *((WORD*)&uuid64 + 3));

    return pszUDN;
}


HANDLE RegisterSSDPService(
  DWORD dwLifeTime,
  PCWSTR pStrDescUrl,
  PCWSTR pStrUDN,
  PCWSTR pStrType) 
{

  HANDLE hReturn = NULL;

  SSDP_MESSAGE    msg;
  
  CHAR            aStrBuffer  [MAX_STRING];
  CHAR            aStrUdn     [MAX_STRING];
  CHAR            aStrType    [MAX_STRING];
  CHAR            aStrDescUrl [MAX_STRING];
  
  memset(&msg, 0, sizeof(msg));

  wcstombs ( aStrDescUrl ,pStrDescUrl, MAX_STRING);
  wcstombs (aStrUdn, pStrUDN, MAX_STRING);
  wcstombs (aStrType, pStrType, MAX_STRING);

  if (pStrUDN == pStrType)
  {
    // uuid:deviceUUID
    strcpy(aStrBuffer, aStrUdn);
  }
  else
  {
    // one of the following :-
    // uuid:deviceUUID::upnp:rootDevice
    // uuid:deviceUUID::urn:schemas-upnp-org:device:deviceType:v
    // uuid:deviceUUID::urn:schemas-upnp-org:service:serviceType:v 
    sprintf(aStrBuffer, "%s::%s", aStrUdn, aStrType);
  }

  msg.iLifeTime     = dwLifeTime;
  msg.szLocHeader   = aStrDescUrl;
  msg.szType        = aStrType;
  msg.szUSN         = aStrBuffer;

  RegisterUpnpServiceImpl(&msg, 0, &hReturn);
  
  return hReturn;
}


#if UNDER_CE
//
// hack to do Initialize in a worker thread,
// because OLE mucks with TLS
// 
// static 
DWORD 
HostedDeviceTree::Initialize2(void *param)
{
    struct HDTInitInfo *pHDTI = (struct HDTInitInfo *)(param);
    
    pHDTI->fRet = pHDTI->pHDT->Initialize(&pHDTI->devInfo, pHDTI->hOwnerProc, pHDTI->hOwner);
    
    return 0;
}
#endif

BOOL
HostedDeviceTree::Initialize(UPNPDEVICEINFO *pDevInfo, HANDLE hOwnerProc, HANDLE hOwner)
{
    BOOL fRet = TRUE;
    
    if (pDevInfo->pszUDN && pDevInfo->pszUDN[0])
        // UDN was specified -> use it
        m_pszUDN = StrDupW(pDevInfo->pszUDN);
    else
        // generate a UDN
        m_pszUDN = ::CreateUDN();

    m_pfCallback = pDevInfo->pfCallback;
    m_pvCallbackContext = pDevInfo->pvUserDevContext;
    m_hOwner = hOwner;  
    m_hOwnerProc = hOwnerProc;  
    m_pszName = StrDupW(pDevInfo->pszDeviceName);

    if(pDevInfo->cachecontrol != 0)
        m_dwLifeTime = max(pDevInfo->cachecontrol, MINIMUM_PUBLISH_INTERVAL);

    INT nChars;
    Assert(!m_pszDescFileName);
    // conjure up a suitable filename for the published device description file
    // "\windows\upnp\" "MyDevice" ".xml"
    nChars = celems(c_szLocalWebRootDir)+wcslen(m_pszName)+5;
    m_pszDescFileName = new WCHAR [nChars];
    if (!m_pszDescFileName)
        fRet = FALSE;
    else 
    {
        nChars -= wsprintfW(m_pszDescFileName, L"%s%s.xml",c_szLocalWebRootDir, m_pszName );
        Assert(nChars >=0);
    }

    if (fRet)
        // parse device description
        fRet = Parse(pDevInfo->pszDeviceDescription);

    if (fRet)
        m_state = DevTreeInitialized;

    return fRet;
}



BOOL
HostedDeviceTree::Publish()
{
    BOOL fRet;
    TraceTag(ttidPublish, "%s: [%08x] Publish\n", __FUNCTION__, this);

    if (m_state >= DevTreePublished)
        return FALSE;   // already published

    if (m_state < DevTreeInitialized)
        return FALSE;   // not yet initialized

    // determine the device description URL
    if (!m_pszDescURL)
    {
        int nChars;
        // skip past the web root path e.g) \windows\upnp
        PCWSTR pch = m_pszDescFileName+celems(c_szLocalWebRootDir)-1;
        nChars = wcslen(pch) + celems(c_szHttpPrefix) + celems(c_szReplaceAddrGuid) + celems(c_szURLPrefix) + 1;
        m_pszDescURL = new WCHAR [nChars];

        if (!m_pszDescURL)
            return FALSE;

        nChars -= wsprintfW(m_pszDescURL, L"%s%S%s%s", c_szHttpPrefix, c_szReplaceAddrGuid, c_szURLPrefix, pch);

        Assert(nChars > 0);

    }
    fRet = FALSE;

    Lock();

    // publish the rootdevice
    m_hSSDPRoot = RegisterSSDPService(m_dwLifeTime, m_pszDescURL, UDN(), L"upnp:rootdevice");

    if (VALIDSSDPH(m_hSSDPRoot))
    {
        // Register each of the devices and services with SSDP in order to send out the announcements
        fRet = m_pRootDevice->SsdpRegister(m_dwLifeTime, m_pszDescURL);

        if (!fRet)
        {
            DeregisterUpnpService(m_hSSDPRoot, TRUE);
            m_hSSDPRoot = INVALID_HANDLE_VALUE;
        }
    }

    if (fRet)
        m_state = DevTreePublished;

    Unlock();

    TraceTag(ttidPublish, "%s: [%08x] Published\n", __FUNCTION__, this);
    return fRet;
}

BOOL
HostedDeviceTree::Unpublish()
{
    BOOL fRet = FALSE;
    TraceTag(ttidPublish, "%s: [%08x] Unpublish\n", __FUNCTION__, this);

    Lock();

    if (m_state >= DevTreePublished)
    {
        if (VALIDSSDPH(m_hSSDPRoot))
        {
            fRet = DeregisterUpnpService(m_hSSDPRoot,TRUE);
            m_hSSDPRoot = INVALID_HANDLE_VALUE;
        }
        fRet &= m_pRootDevice->SsdpUnregister();

        m_state = DevTreeInitialized;
    }

    Unlock();

    TraceTag(ttidPublish, "%s: [%08x] Unpublished\n", __FUNCTION__, this);
    return fRet;
}

BOOL
HostedDeviceTree::SubmitPropertyEvent(
    PCWSTR szUDN,
    PCWSTR szServiceId,
    DWORD dwFlags,
    DWORD nArgs,
    UPNPPARAM *rgArgs)
{
    HostedService *pService;
    BOOL fRet = FALSE;

    TraceTag(ttidTrace, "%s: [%08x] Submit Property Event UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, szServiceId);
    Lock();

    if (m_state >= DevTreeInitialized)
    {
        pService = FindService(szUDN, szServiceId);
        if (pService)
        {
            fRet = pService->SubmitPropertyEvent(dwFlags, nArgs, rgArgs);
        }
    }

    Unlock();
    TraceTag(ttidTrace, "%s: [%08x] Submited Property Event UDN[%S] ServiceID[%S]\n", __FUNCTION__, this, szUDN, szServiceId);
    return fRet;
}

HostedDeviceTree::~HostedDeviceTree()
{
    delete m_pRootDevice;
    delete m_pTempDevice;
    delete m_pszURLBase;
    delete m_pszDescURL;
    delete m_pszDescFileName;
    delete m_pszName;
    delete m_pszUDN;

    DeleteCriticalSection(&m_cs);
}

BOOL HostedDeviceTree::Shutdown(DWORD dwFlags)
{
    DWORD dwStatus;
    TraceTag(ttidTrace, "%s: [%08x] Shutdown\n", __FUNCTION__, this);

    Lock();

    Unpublish();
    m_state = DevTreeInvalid;
    m_hShutdownEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

    Unlock();

    if (! (dwFlags & HDT_NO_CALLBACKS))
    {
        // notify device owner that his device is going away
        DoDeviceCallback(NULL, UPNPCB_SHUTDOWN, NULL, NULL, NULL);
    }

    DecRef();   // normally decrements to zero
    dwStatus = WaitForSingleObject(m_hShutdownEvent, 15000);

    AssertSz(dwStatus == WAIT_OBJECT_0, "HostedDeviceTree not released on shutdown!");

    CloseHandle(m_hShutdownEvent);
    m_hShutdownEvent = NULL;

    DeleteFile(m_pszDescFileName);

    TraceTag(ttidTrace, "%s: [%08x] Shutdown Complete\n", __FUNCTION__, this);
    return TRUE;
}


// CreateUDN
void HostedDeviceTree::CreateUDN(LPWSTR *ppUDN)
{
    Assert(ppUDN);
    Assert(!*ppUDN);
    
    if(!m_nUDNSuffix)
    {
        // root device
        *ppUDN = StrDupW(m_pszUDN);
    }
    else
    {
        // embedded device
        int cchUDN = wcslen(m_pszUDN) + 11; // max size of integer string

        *ppUDN = new WCHAR [cchUDN];

        if (*ppUDN)
        {
            cchUDN -= wsprintfW(*ppUDN, L"%.37s%04x", m_pszUDN, m_nUDNSuffix);
            Assert(cchUDN > 0);
        }
    }

    m_nUDNSuffix++;
}


HostedDevice::~HostedDevice()
{
    delete m_pNextDev;
    delete m_pFirstChildDev;
    delete m_pFirstService;
    delete m_pszUDN;
    delete m_pszOrigUDN;
    delete m_pszDeviceType;
}


BOOL HostedDevice::SsdpRegister(DWORD dwLifeTime, PCWSTR pszDescURL )
{
    BOOL fRet = TRUE;
    // publish the UDN
    m_hSSDPUDN = RegisterSSDPService(dwLifeTime, pszDescURL, m_pszUDN, m_pszUDN);
    // publish the device Type
    m_hSSDPDevType = RegisterSSDPService(dwLifeTime, pszDescURL, m_pszUDN, m_pszDeviceType);

    if (VALIDSSDPH(m_hSSDPUDN) && VALIDSSDPH(m_hSSDPDevType))
    {
        HostedService *pService;
        fRet = TRUE;
        for (pService=m_pFirstService;pService;pService=pService->NextService())
        {
            fRet = pService->SsdpRegister(dwLifeTime, pszDescURL, m_pszUDN);
        }
        

⌨️ 快捷键说明

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