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

📄 finder.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        pfcb->Lock();
    }
    else
        ASSERT(FALSE);

    pfcb->Unlock();
    pfcb->Release();
}


void FinderCallback::PerformCallback(SSDP_CALLBACK_TYPE cbType, BSTR bstrUDN, IUPnPDevice* pUPnPDevice)
{
    HRESULT hr;

    if(fDispatch)
    {
        ce::variant varResult;
        ce::variant avarArgs[3];

        avarArgs[0].vt = VT_I4;

        switch(cbType)
        {
            case SSDP_ALIVE:
            case SSDP_FOUND:

                ASSERT(pUPnPDevice);

                // 1st argument is pointer to device object
                avarArgs[2].vt = VT_DISPATCH;
                pUPnPDevice->QueryInterface(IID_IDispatch, (LPVOID *)(&avarArgs[2].pdispVal));

                // 2nd argument is device UDN
                avarArgs[1] = bstrUDN;

                // 3rd argument is type of callback
                V_I4(&avarArgs[0]) = 0;
                break;

            case SSDP_BYEBYE:
                // 1st argument not used for "device removed" callback

                // 2nd argument is device UDN
                avarArgs[1] = bstrUDN;

                // 3rd argument is type of callback - string "1" indicates "device removed"
                V_I4(&avarArgs[0]) = 1;
                break;

            case SSDP_DONE:
                // 1st argument not used for "search complete" callback

                // 2nd argument not used for "search complete" callback

                // 3rd argument is type of callback - string "2" indicates "search complete"
                V_I4(&avarArgs[0]) = 2;

                DEBUGMSG(ZONE_CALLBACK, (L"UPNP:ServiceCallback-Search complete.\n"));
                break;

            default:
                ASSERT(FALSE);
                break;
        }

        DISPPARAMS dispParams = {0};

        dispParams.rgvarg = &avarArgs[0];
        dispParams.cArgs = 3;

        hr = cb.pDispatch->Invoke(DISPID_VALUE, IID_NULL, 0, DISPATCH_METHOD, &dispParams, &varResult, NULL, NULL);

        if (hr != S_OK)
        {
            DEBUGMSG(ZONE_ERROR, (L"UPNP:Invoke on DeviceFinderCallback returns 0x%08x\n", hr));
        }
    }
    else
    {
        switch(cbType)
        {
            case SSDP_ALIVE:
            case SSDP_FOUND:
                ASSERT(pUPnPDevice);
                hr = cb.pCallback->DeviceAdded((LONG)this, pUPnPDevice);
                break;

            case SSDP_BYEBYE:
                hr = cb.pCallback->DeviceRemoved((LONG)this, bstrUDN);
                break;

            case SSDP_DONE:
                hr = cb.pCallback->SearchComplete((LONG)this);

                DEBUGMSG(ZONE_CALLBACK, (L"UPNP:ServiceCallback-Search complete.\n"));
                break;

            default:
                ASSERT(FALSE);
                break;
        }
    }
}


// Find
HRESULT CUPnPDeviceFinder::Find(BSTR bstrSearchTarget, IUPnPDevices **ppDevices, IUPnPDevice **ppDevice)
{
    ASSERT((ppDevices != NULL) ^ (ppDevice != NULL));   //exactly one of them has to be NULL

    HRESULT                                                                                     hr = E_FAIL;
    ce::auto_xxx<HANDLE, BOOL (__stdcall *)(HANDLE), FindServicesClose, INVALID_HANDLE_VALUE>   hFind;
    ce::string                                                                                  strSearchTarget;

    // ANSI code page for URI
    ce::WideCharToMultiByte(CP_ACP, bstrSearchTarget, -1, &strSearchTarget);

    // find services
    hFind = FindServices(strSearchTarget, NULL, TRUE);

    if(!hFind.valid())
    {
        DEBUGMSG(ZONE_ERROR, (L"FindServices returns INVALID_HANDLE_VALUE\n"));

        return HrFromLastWin32Error();
    }

    Devices* pDevices = NULL;

    if(ppDevices)
    {
        // create output collection
        pDevices = new Devices();

        if(!pDevices)
            return E_OUTOFMEMORY;
    }

    PSSDP_MESSAGE pService = NULL;

    // iterate through found services 
    for(BOOL bContinue = GetFirstService(hFind, &pService); bContinue && pService; bContinue = GetNextService(hFind, &pService))
    {
        IFDBG(DumpSSDPMessage(pService));

        IUPnPDevice *pUPnPDevice = NULL;

        // get device for the service
        if(SUCCEEDED(hr = GetUPnPDevice(pService->szUSN, pService->szLocHeader, pService->iLifeTime, &pUPnPDevice)))
        {
            ASSERT(pUPnPDevice);

            if(ppDevice)
            {
                // searching by UDN - there should be just one result
                // return as soon as we find one
                *ppDevice = pUPnPDevice;
                break;
            }
            else
            {
                ASSERT(pDevices);
                // searching by type - there might be multiply results
                // add found device to collection
                ce::auto_bstr bstrUDN;

                pUPnPDevice->get_UniqueDeviceName(&bstrUDN);
                pDevices->AddItem(bstrUDN, pUPnPDevice);
            }

            pUPnPDevice->Release();
        }
    }

    if(pDevices)
        if(SUCCEEDED(hr))
            hr = pDevices->QueryInterface(IID_IUPnPDevices, (void**)ppDevices);
        else
            delete pDevices;

    return hr;
}


// FindByType
STDMETHODIMP
CUPnPDeviceFinder::FindByType(  /* [in] */          BSTR bstrTypeURI,
                                /* [in] */          DWORD dwFlags,
                                /* [out, retval] */ IUPnPDevices ** ppDevices)
{
    DEBUGMSG(ZONE_FINDER, (L"IUPnPDeviceFinder::FindByType(bstrTypeURI=%s, dwFlags=0x%08x).\n", bstrTypeURI, dwFlags));

    return Find(bstrTypeURI, ppDevices, NULL);
}


// FindByUDN
STDMETHODIMP
CUPnPDeviceFinder::FindByUDN(   /*[in]*/ BSTR bstrUDN,
                                /*[out, retval]*/ IUPnPDevice ** ppDevice)
{
    DEBUGMSG(ZONE_FINDER, (L"IUPnPDeviceFinder::FindByUDN(bstrTypeUDN=%s).\n", bstrUDN));

    return Find(bstrUDN, NULL, ppDevice);
}


// CreateAsyncFind
STDMETHODIMP
CUPnPDeviceFinder::CreateAsyncFind( /* [in] */          BSTR bstrTypeURI,
                                    /* [in] */          DWORD dwFlags,
                                    /* [in] */          IUnknown __RPC_FAR *punkDeviceFinderCallback,
                                    /* [retval][out] */ LONG __RPC_FAR *plFindData)
{
    CHECK_POINTER(plFindData);
    CHECK_POINTER(punkDeviceFinderCallback);
    CHECK_POINTER(bstrTypeURI);

    FinderCallback *pfcb = new FinderCallback;
    if (!pfcb)
        return E_OUTOFMEMORY;

    pfcb->dwSig = FINDERCBSIG;
    pfcb->bstrSearchTarget = SysAllocString(bstrTypeURI);
    pfcb->dwFlags = dwFlags;
    pfcb->fDispatch = FALSE;

    if(!pfcb->Valid())
    {
        pfcb->Release();
        return E_FAIL;
    }

    if (FAILED(punkDeviceFinderCallback->QueryInterface(IID_IUPnPDeviceFinderCallback, (LPVOID *)&(pfcb->cb.pCallback))))
    {
        pfcb->fDispatch = TRUE;
        if (FAILED(punkDeviceFinderCallback->QueryInterface(IID_IDispatch, (LPVOID *)&(pfcb->cb.pDispatch))))
        {
            DEBUGMSG(ZONE_ERROR|ZONE_FINDER, (L"IUPnPDeviceFinder::CreateAsyncFind:punkDeviceFinderCallback supports neither IDispatch nor IUPnPDeviceFinderCallback.\n"));
            pfcb->Release();
            return E_FAIL;
        }
    }

    pfcb->hFind = INVALID_HANDLE_VALUE;
    
    Lock();

    pfcb->pNext = _pfcbFirst;
    _pfcbFirst = pfcb;

    Unlock();

    *plFindData = (LONG)pfcb;

    return S_OK;
}


// StartAsyncFind
STDMETHODIMP
CUPnPDeviceFinder::StartAsyncFind(/* [in] */ LONG lFindData)
{
    Lock();

    FinderCallback *pfcb = _pfcbFirst;
    FinderCallback *pfcbPrev = NULL;

    // look for the async find object
    while (pfcb && (lFindData != (LONG )pfcb))
    {
        pfcbPrev = pfcb;
        pfcb = pfcb->pNext;
    }

    if (!pfcb)
    {
        DEBUGMSG(ZONE_ERROR|ZONE_FINDER, (L"IUPnPDeviceFinder::StartAsyncFind:Invalid cookie-%d.\n", lFindData));
        Unlock();
        return E_INVALIDARG;
    }

    ce::string  strSearchTarget;

    // ANSI code page for search target
    ce::WideCharToMultiByte(CP_ACP, pfcb->bstrSearchTarget, -1, &strSearchTarget);

    pfcb->start_listening();

    pfcb->hFind = FindServicesCallback(strSearchTarget, NULL, TRUE, ServiceCallback, pfcb);

    DEBUGMSG(ZONE_FINDER, (L"IUPnPDeviceFinder::StartAsyncFind:FindServicesCallback returns handle=0x%08x.\n", pfcb->hFind));

    //  The find is cancelled if StartAsyncFind fails
    HRESULT hr = S_OK;

    if (pfcb->hFind == INVALID_HANDLE_VALUE)
    {
        pfcb->stop_listening();

        hr = HrFromLastWin32Error();
        if (!pfcbPrev)
            _pfcbFirst = pfcb->pNext;
        else
            pfcbPrev->pNext = pfcb->pNext;

        pfcb->Release();
    }

    Unlock();

    return hr;
}


// CancelAsyncFind
STDMETHODIMP
CUPnPDeviceFinder::CancelAsyncFind(/* [in] */ LONG lFindData)
{
    Lock();

    FinderCallback *pfcb = _pfcbFirst;
    FinderCallback *pfcbPrev = NULL;

    // look for the async find object
    while (pfcb && (lFindData != (LONG )pfcb))
    {
        pfcbPrev = pfcb;
        pfcb = pfcb->pNext;
    }

    if (!pfcb)
    {
        DEBUGMSG(ZONE_ERROR|ZONE_FINDER, (L"IUPnPDeviceFinder::CancelAsyncFind:Invalid cookie-%d.\n", lFindData));
        Unlock();
        return E_INVALIDARG;
    }

    // release find object resources
    if (pfcb->hFind != INVALID_HANDLE_VALUE)
        FindServicesClose(pfcb->hFind);

    // remove find object from the list
    if (!pfcbPrev)
        _pfcbFirst = pfcb->pNext;
    else
        pfcbPrev->pNext = pfcb->pNext;

    Unlock();

    // release find object
    pfcb->FinalRelease();

    return S_OK;
}


⌨️ 快捷键说明

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