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

📄 devsvc.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
#include <devsvc.h>
#include <httpext.h>



CRITICAL_SECTION g_csUPNP;
LIST_ENTRY g_DevTreeList;

static HostedDeviceTree *FindDevTreeByName(PCWSTR pszDevTreeName)
{
    LIST_ENTRY *pLink;
    for (pLink = g_DevTreeList.Flink; pLink != &g_DevTreeList; pLink = pLink->Flink)
    {
        HostedDeviceTree *pDevTree;
        pDevTree = CONTAINING_RECORD(pLink, HostedDeviceTree, m_link);
        if (wcscmp(pszDevTreeName, pDevTree->Name()) == 0)
            return pDevTree;
    }
    return NULL;
}

static HostedDeviceTree *FindDevTreeSafe(PCWSTR pszDevName)
{
    HostedDeviceTree *pDevTree = NULL;
    EnterCriticalSection(&g_csUPNP);
    __try {
        pDevTree = FindDevTreeByName(pszDevName);

        if (!pDevTree)
        {
            SetLastError(ERROR_FILE_NOT_FOUND);
            __leave;
        }
        pDevTree->IncRef();
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
    }
    LeaveCriticalSection(&g_csUPNP);

    return pDevTree;
}

// find HostedDevTree by UDN. If found, increment refcount and return pointer

static HostedDeviceTree *FindDevTreeByUDN(PCWSTR pszUDN)
{
    HostedDeviceTree    *pDevTree = NULL;
    LIST_ENTRY          *pLink;

    EnterCriticalSection(&g_csUPNP);
    for (pLink = g_DevTreeList.Flink; pLink != &g_DevTreeList; pLink = pLink->Flink)
    {
        pDevTree = CONTAINING_RECORD(pLink, HostedDeviceTree, m_link);

        if(NULL != pDevTree->FindDevice(pszUDN))
        {
            pDevTree->IncRef();
            break;
        }
    }

    LeaveCriticalSection(&g_csUPNP);

    if(pLink == &g_DevTreeList)
        return NULL;

    return pDevTree;
}

HostedDeviceTree *FindDevTreeAndServiceIdFromUri(PCSTR pszaUri, PWSTR *ppszUDN, PWSTR *ppszSid)
{
    // szaUri is  "UDN+ServiceID"
    const CHAR                *pszaSid;
    HostedDeviceTree    *pDevTree = NULL;
    PWSTR               pszUDN;

    *ppszUDN = NULL;
    *ppszSid = NULL;
    
    pszaSid = strchr(pszaUri, '+');

    if (!pszaSid)
        return FALSE;

    pszUDN = new WCHAR [pszaSid - pszaUri + 1];

    if (pszUDN) {
        mbstowcs(pszUDN, pszaUri, pszaSid - pszaUri);
        pszUDN[pszaSid - pszaUri] = 0;  // null terminate;
        pDevTree = FindDevTreeByUDN(pszUDN);

        if(pDevTree)
            *ppszUDN = pszUDN;
        else        
            delete [] pszUDN;
    }

    pszaSid++;

    if (pDevTree)
    {
        if (ppszSid)
        {
            *ppszSid = StrDupAtoW(pszaSid);
            if (!*ppszSid)
            {
                pDevTree->DecRef();
                pDevTree = NULL;

                delete *ppszUDN;
                *ppszUDN = NULL;
            }
        }
    }

    return pDevTree;
}



/*
 *  UPnP Service Interface
 *
 *      - upnpsvc interface routines
 *      - parameter checking delegates
 *
 */


// FORWARD Declarations
BOOL UpnpAddDeviceImpl(__in HANDLE hOwner, __in UPNPDEVICEINFO* pDevInfo);
BOOL UpnpRemoveDeviceImpl(__in PCWSTR pszDeviceName);
BOOL UpnpPublishDeviceImpl(__in PCWSTR pszDeviceName);
BOOL UpnpUnpublishDeviceImpl(__in PCWSTR pszDeviceName); 
BOOL UpnpGetUDNImpl(__in PCWSTR pszDeviceName, __in PCWSTR pszTemplateUDN, __out ce::psl_buffer_wrapper<PWSTR>& UDNBuf, __out PDWORD pcchBuf);
BOOL UpnpGetSCPDPathImpl(__in PCWSTR pszDeviceName, __in PCWSTR pszUDN, __in PCWSTR pszServiceId, __out ce::psl_buffer_wrapper<PWSTR>& SCPDFilePath);
BOOL SetRawControlResponseImpl(__in DWORD hRequest, __in DWORD dwHttpStatus, __in PCWSTR pszResp);
BOOL UpnpSubmitPropertyEventImpl(__in PCWSTR pszDeviceName, __in PCWSTR pszUDN, __in PCWSTR pszServiceId, __in ce::psl_buffer_wrapper<UPNPPARAM*> Args);
BOOL UpnpUpdateEventedVariablesImpl(PCWSTR pszDeviceName, PCWSTR pszUDN, PCWSTR pszServiceId, ce::psl_buffer_wrapper<UPNPPARAM*> Args);
BOOL ReceiveInvokeRequestImpl(__in DWORD retCode, __out ce::psl_buffer_wrapper<PBYTE>& pReqBuf, __out PDWORD pcbReqBuf);



/*
 *  UpnpAddDeviceImpl:
 *
 *      - perform parameter checking then differ to delegate
 *
 */
BOOL UpnpAddDeviceImpl(__in HANDLE hOwner, __in ce::marshal_arg<ce::copy_in, UPNPDEVICEINFO*> pDevInfo)
{
    if (!pDevInfo || 
        pDevInfo->cbStruct != sizeof(UPNPDEVICEINFO) || 
        !pDevInfo->pszDeviceDescription || 
        !pDevInfo->pszDeviceName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return UpnpAddDeviceImpl(hOwner, static_cast<UPNPDEVICEINFO*>(pDevInfo));
}



/*
 *  UpnpAddDeviceImpl:
 *
 *      - create a new HostedDeviceTree object representing the upnp device
 *
 */
BOOL UpnpAddDeviceImpl(__in HANDLE hOwner, __in UPNPDEVICEINFO* pDevInfo)
{
    DWORD error = NO_ERROR;
    BOOL fRet = FALSE;
    HostedDeviceTree *pDevTree;

    EnterCriticalSection(&g_csUPNP);

    pDevTree = FindDevTreeByName(pDevInfo->pszDeviceName);
    if (pDevTree)
    {
        error = ERROR_ALREADY_EXISTS;
        goto Finish;
    }

    pDevTree = new HostedDeviceTree();
    if (!pDevTree)
    {
        error = ERROR_OUTOFMEMORY;
        goto Finish;
    }

    // because we can't load MSXML in a borrowed thread without sideeffects
    // the following hack is to do the initialization in another thread

#pragma warning(push)
#pragma warning(disable:4068)  // warning C4068: unknown pragma
#pragma prefast(disable:11)    // prefast bug - doesn't understand variable declaration in a conditional

    if(struct HDTInitInfo *pinitInfo = new struct HDTInitInfo)
    {
        pinitInfo->pHDT = pDevTree;
        pinitInfo->devInfo.cbStruct = sizeof(pinitInfo->devInfo);
        pinitInfo->devInfo.pszDeviceDescription = StrDupW(pDevInfo->pszDeviceDescription);
        pinitInfo->devInfo.pszDeviceName = StrDupW(pDevInfo->pszDeviceName);
        pinitInfo->devInfo.pszUDN = StrDupW(pDevInfo->pszUDN);
        pinitInfo->devInfo.cachecontrol = pDevInfo->cachecontrol;
        pinitInfo->devInfo.pfCallback = pDevInfo->pfCallback;
        pinitInfo->devInfo.pvUserDevContext = pDevInfo->pvUserDevContext;
        pinitInfo->hOwner = hOwner;
        pinitInfo->hOwnerProc = GetCallerProcess();
        pinitInfo->fRet = FALSE;

        HANDLE h = CreateThread(NULL, 0, HostedDeviceTree::Initialize2, pinitInfo, 0, NULL);

        if(h)
        {
            DWORD dwWait;
            dwWait = WaitForSingleObject(h, INFINITE);
            Assert(dwWait == WAIT_OBJECT_0);
            CloseHandle(h);
        }

        fRet = pinitInfo->fRet;
        delete pinitInfo->devInfo.pszDeviceDescription;
        delete pinitInfo->devInfo.pszDeviceName;
        delete pinitInfo->devInfo.pszUDN;
        delete pinitInfo;
    }
#pragma prefast(enable:11)
#pragma warning(pop)


    if (!fRet)
    {
        delete pDevTree;
        pDevTree = NULL;
    }
    else
    {
        pDevTree->IncRef();     // set the refcount to 1
        pDevTree->AddToList(&g_DevTreeList);
    }

Finish:
    LeaveCriticalSection(&g_csUPNP);

    if (error)
    {
        fRet = FALSE;
        SetLastError(error);
    }
    return fRet;
}



/*
 *  UpnpRemoveDeviceImpl:
 *
 *      - perform parameter checking and differ to delegate
 *      - pszDeviceName must be non-null and not the empty-string
 *
 */
BOOL UpnpRemoveDeviceImpl(__in ce::marshal_arg<ce::copy_in, PCWSTR> pszDeviceName)
{
    if(!pszDeviceName || !*pszDeviceName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return UpnpRemoveDeviceImpl((PCWSTR) pszDeviceName);
}



/*
 *  UpnpRemoveDeviceImpl:
 *
 *      - find the HostedDeviceTree from the device name
 *      - remove the HostedDeviceTree from the device list
 *      - shutdown the device and cleanup resource allocations
 *
 */
BOOL UpnpRemoveDeviceImpl(__in PCWSTR pszDeviceName)
{
    HostedDeviceTree *pDevTree = NULL;
    EnterCriticalSection(&g_csUPNP);

    pDevTree = FindDevTreeByName(pszDeviceName);

    if (!pDevTree)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        goto Finish;
    }

    pDevTree->RemoveFromList();

Finish:
    LeaveCriticalSection(&g_csUPNP);

    if (pDevTree)
    {
        pDevTree->Shutdown();
        delete pDevTree;
        return TRUE;
    }

    return FALSE;
}



/*
 *  UpnpPublishDeviceImpl:
 *
 *      - perform parameter checking and differ to delegate
 *      - pszDeviceName must be non-null and not the empty-string
 *
 */
BOOL UpnpPublishDeviceImpl(__in ce::marshal_arg<ce::copy_in, PCWSTR> pszDeviceName)
{
    if(!pszDeviceName || !*pszDeviceName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return UpnpPublishDeviceImpl((PCWSTR) pszDeviceName);
}



/*
 *  UpnpPublishDeviceImpl:
 *
 *      - publish the specified device
 *
 */
BOOL UpnpPublishDeviceImpl(__in PCWSTR pszDeviceName)
{
    BOOL fRet;
    HostedDeviceTree *pDevTree;

    pDevTree = FindDevTreeSafe(pszDeviceName);

    fRet = FALSE;
    if (pDevTree)
    {
        fRet = pDevTree->Publish();
        pDevTree->DecRef();
    }
    return fRet;
}



/*
 *  UpnpUnpublishDeviceImpl:
 * 
 *      - perform parameter checking and differ to delegate
 *      - pszDeviceName must be non-null and not the empty-string
 *
 */
BOOL UpnpUnpublishDeviceImpl(__in ce::marshal_arg<ce::copy_in, PCWSTR> pszDeviceName)
{
    if(!pszDeviceName || !*pszDeviceName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return UpnpUnpublishDeviceImpl((PCWSTR) pszDeviceName);
}


/*
 *  UpnpUnpublishDeviceImpl:
 *
 *      - unpublish the specified device
 *
 */
BOOL UpnpUnpublishDeviceImpl(__in PCWSTR pszDeviceName)
{
    BOOL fRet;
    HostedDeviceTree *pDevTree;

    pDevTree = FindDevTreeSafe(pszDeviceName);

    fRet = FALSE;
    if (pDevTree)
    {
        fRet = pDevTree->Unpublish();
        pDevTree->DecRef();
    }
    return fRet;
}



/*
 *  UpnpGetUDNImpl:
 *
 *      - ensure that the device name is not null or empty string
 *      - ensure that the UDN buffer count is not 0
 *      - ensure that the UDN buffer size pointer is not null
 *
 */
BOOL
UpnpGetUDNImpl(
    __in ce::marshal_arg<ce::copy_in, PCWSTR>                            pszDeviceName,      // [in] local device name
    __in ce::marshal_arg<ce::copy_in, PCWSTR>                            pszTemplateUDN,     // [in, optional] the UDN element in the original device description
    __out ce::marshal_arg<ce::copy_out, ce::psl_buffer_wrapper<PWSTR> >  UDNBuf,             // [out] UDN buffer
    __out ce::marshal_arg<ce::copy_out, PDWORD>                          pcchBuf)            // [out] size of buffer/ length filled (in WCHARs)
{
    if(!pszDeviceName || !*pszDeviceName)
    {
        goto Finish;
    }

    if(!(UDNBuf.count()) || !pcchBuf)
    {
        goto Finish;
    }

    return UpnpGetUDNImpl((PCWSTR) pszDeviceName,
                          static_cast<PCWSTR>(pszTemplateUDN),
                          static_cast<ce::psl_buffer_wrapper<PWSTR> >(UDNBuf),
                          static_cast<PDWORD>(pcchBuf));

Finish:
    SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
}



/*
 *  UpnpGetUDNImpl:
 *
 *      - get device UDN based on device name
 *      - copy UDN into the UDN buffer and indicate the size in pcchBuf
 *
 */
BOOL UpnpGetUDNImpl(__in PCWSTR pszDeviceName, __in PCWSTR pszTemplateUDN, __out ce::psl_buffer_wrapper<PWSTR>& UDNBuf, __out PDWORD pcchBuf)
{
    BOOL fRet = FALSE;
    HostedDeviceTree *pDevTree;

    pDevTree = FindDevTreeSafe(pszDeviceName);

    if (pDevTree)
    {
        HostedDevice *pDev;
        pDev = pDevTree->FindDeviceByOrigUDN(pszTemplateUDN);
        if (pDev && pDev->UDN())
        {
            DWORD cch = wcslen(pDev->UDN())+1;
            if (UDNBuf.count() >= cch)
            {
                wcscpy(UDNBuf.buffer(), pDev->UDN());
                fRet = TRUE;
            }
            else
            {
                SetLastError(ERROR_INSUFFICIENT_BUFFER);

⌨️ 快捷键说明

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