windows-nt/Source/XPSP1/NT/net/upnp/ssdp/common/ssdpsrv/search.cpp
2020-09-26 16:20:57 +08:00

138 lines
3.1 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: S E A R C H . C P P
//
// Contents: SSDP Search Response
//
// Notes:
//
// Author: mbend 10 Nov 2000
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "search.h"
#include "ssdpfunc.h"
#include "ncbase.h"
#include "announce.h"
// response ahead 1 second
#define RESPONSE_AHEAD 0.5
CSsdpSearchResponse::CSsdpSearchResponse()
: m_timer(*this), m_szResponse(NULL)
{
}
CSsdpSearchResponse::~CSsdpSearchResponse()
{
delete [] m_szResponse;
m_szResponse = NULL;
}
HRESULT CSsdpSearchResponse::HrCreate(SOCKET * pSockLocal,
SOCKADDR_IN * pSockRemote,
char * szResponse, long nMX)
{
HRESULT hr = S_OK;
CSsdpSearchResponse * pResponse = new CSsdpSearchResponse();
if(!pResponse)
{
delete [] szResponse;
hr = E_OUTOFMEMORY;
}
if(SUCCEEDED(hr))
{
hr = pResponse->HrInitialize(pSockLocal, pSockRemote, szResponse, nMX);
if(SUCCEEDED(hr))
{
long nDelay = pResponse->CalculateDelay();
TraceTag(ttidSsdpSearchResp, "CSsdpSearchResponse::HrCreate - "
"timer started for %d", nDelay);
hr = pResponse->m_timer.HrSetTimer(nDelay);
}
else
{
delete [] szResponse;
}
if(FAILED(hr))
{
delete pResponse;
}
}
TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::HrCreate");
return hr;
}
HRESULT CSsdpSearchResponse::HrInitialize(
SOCKET * pSockLocal,
SOCKADDR_IN * pSockRemote,
char * szResponse,
long nMX)
{
HRESULT hr = S_OK;
m_sockLocal = *pSockLocal;
m_sockRemote = *pSockRemote;
m_nMX = nMX;
m_szResponse = szResponse;
TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::HrInitialize");
return hr;
}
long CSsdpSearchResponse::CalculateDelay()
{
// Range = (ResponseEntry->MX - 0);
float nRange = (float)m_nMX;
long nDelay;
if (nRange > RESPONSE_AHEAD)
{
nRange -= RESPONSE_AHEAD;
nDelay = (long)((rand() * nRange / RAND_MAX) * 1000.0);
}
else
{
nDelay = 0;
}
return nDelay;
}
void CSsdpSearchResponse::TimerFired()
{
HRESULT hr = S_OK;
if (FReferenceSocket(m_sockLocal))
{
SocketSendWithReplacement(m_szResponse, &m_sockLocal, &m_sockRemote);
UnreferenceSocket(m_sockLocal);
}
TraceTag(ttidSsdpSearchResp, "Sending search response: %s", m_szResponse);
// This will queue ourselves to autodelete
hr = HrStart(TRUE, FALSE);
TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::TimerFired");
}
DWORD CSsdpSearchResponse::DwRun()
{
// Must lock and queue work item to free ourselves or timer stuff will AV
CLock lock(m_critSec);
m_timer.HrDelete(INVALID_HANDLE_VALUE);
return 0;
}