Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.1 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: S E A R C H . C P P
  7. //
  8. // Contents: SSDP Search Response
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 10 Nov 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.h>
  16. #pragma hdrstop
  17. #include "search.h"
  18. #include "ssdpfunc.h"
  19. #include "ncbase.h"
  20. #include "announce.h"
  21. // response ahead 1 second
  22. #define RESPONSE_AHEAD 0.5
  23. CSsdpSearchResponse::CSsdpSearchResponse()
  24. : m_timer(*this), m_szResponse(NULL)
  25. {
  26. }
  27. CSsdpSearchResponse::~CSsdpSearchResponse()
  28. {
  29. delete [] m_szResponse;
  30. m_szResponse = NULL;
  31. }
  32. HRESULT CSsdpSearchResponse::HrCreate(SOCKET * pSockLocal,
  33. SOCKADDR_IN * pSockRemote,
  34. char * szResponse, long nMX)
  35. {
  36. HRESULT hr = S_OK;
  37. CSsdpSearchResponse * pResponse = new CSsdpSearchResponse();
  38. if(!pResponse)
  39. {
  40. delete [] szResponse;
  41. hr = E_OUTOFMEMORY;
  42. }
  43. if(SUCCEEDED(hr))
  44. {
  45. hr = pResponse->HrInitialize(pSockLocal, pSockRemote, szResponse, nMX);
  46. if(SUCCEEDED(hr))
  47. {
  48. long nDelay = pResponse->CalculateDelay();
  49. TraceTag(ttidSsdpSearchResp, "CSsdpSearchResponse::HrCreate - "
  50. "timer started for %d", nDelay);
  51. hr = pResponse->m_timer.HrSetTimer(nDelay);
  52. }
  53. else
  54. {
  55. delete [] szResponse;
  56. }
  57. if(FAILED(hr))
  58. {
  59. delete pResponse;
  60. }
  61. }
  62. TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::HrCreate");
  63. return hr;
  64. }
  65. HRESULT CSsdpSearchResponse::HrInitialize(
  66. SOCKET * pSockLocal,
  67. SOCKADDR_IN * pSockRemote,
  68. char * szResponse,
  69. long nMX)
  70. {
  71. HRESULT hr = S_OK;
  72. m_sockLocal = *pSockLocal;
  73. m_sockRemote = *pSockRemote;
  74. m_nMX = nMX;
  75. m_szResponse = szResponse;
  76. TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::HrInitialize");
  77. return hr;
  78. }
  79. long CSsdpSearchResponse::CalculateDelay()
  80. {
  81. // Range = (ResponseEntry->MX - 0);
  82. float nRange = (float)m_nMX;
  83. long nDelay;
  84. if (nRange > RESPONSE_AHEAD)
  85. {
  86. nRange -= RESPONSE_AHEAD;
  87. nDelay = (long)((rand() * nRange / RAND_MAX) * 1000.0);
  88. }
  89. else
  90. {
  91. nDelay = 0;
  92. }
  93. return nDelay;
  94. }
  95. void CSsdpSearchResponse::TimerFired()
  96. {
  97. HRESULT hr = S_OK;
  98. if (FReferenceSocket(m_sockLocal))
  99. {
  100. SocketSendWithReplacement(m_szResponse, &m_sockLocal, &m_sockRemote);
  101. UnreferenceSocket(m_sockLocal);
  102. }
  103. TraceTag(ttidSsdpSearchResp, "Sending search response: %s", m_szResponse);
  104. // This will queue ourselves to autodelete
  105. hr = HrStart(TRUE, FALSE);
  106. TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::TimerFired");
  107. }
  108. DWORD CSsdpSearchResponse::DwRun()
  109. {
  110. // Must lock and queue work item to free ourselves or timer stuff will AV
  111. CLock lock(m_critSec);
  112. m_timer.HrDelete(INVALID_HANDLE_VALUE);
  113. return 0;
  114. }