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.

230 lines
5.1 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: R E C E I V E D A T A . C P P
  7. //
  8. // Contents: Queue of received data from network
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 17 Dec 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ReceiveData.h"
  18. #include "ssdp.h"
  19. #include "status.h"
  20. #include "ssdpfunc.h"
  21. #include "ssdptypes.h"
  22. #include "ssdpnetwork.h"
  23. #include "ncbase.h"
  24. #include "event.h"
  25. #include "ncinet.h"
  26. VOID ProcessSsdpRequest(PSSDP_REQUEST pSsdpRequest, RECEIVE_DATA *pData);
  27. CReceiveData::CReceiveData(char * szData, SOCKET sock, BOOL fIsTcpSocket, BOOL fMCast,
  28. SOCKADDR_IN * psockAddrInRemote)
  29. : m_szData(szData), m_pNext(NULL), m_sock(sock), m_fIsTcpSocket(fIsTcpSocket), m_fMCast(fMCast)
  30. {
  31. m_sockAddrInRemote = *psockAddrInRemote;
  32. }
  33. CReceiveData::~CReceiveData()
  34. {
  35. delete [] m_szData;
  36. }
  37. CReceiveDataManager CReceiveDataManager::s_instance;
  38. CReceiveDataManager::CReceiveDataManager() : m_hEventShutdown(NULL), m_hEventWork(NULL), m_hThread(NULL), m_pHead(NULL), m_pTail(NULL)
  39. {
  40. }
  41. CReceiveDataManager::~CReceiveDataManager()
  42. {
  43. if(m_hEventShutdown)
  44. {
  45. CloseHandle(m_hEventShutdown);
  46. m_hEventShutdown = NULL;
  47. }
  48. if(m_hEventWork)
  49. {
  50. CloseHandle(m_hEventWork);
  51. m_hEventWork = NULL;
  52. }
  53. if(m_hThread)
  54. {
  55. CloseHandle(m_hThread);
  56. m_hThread = NULL;
  57. }
  58. }
  59. CReceiveDataManager & CReceiveDataManager::Instance()
  60. {
  61. return s_instance;
  62. }
  63. HRESULT CReceiveDataManager::HrAddData(char * szData, SOCKET sock, BOOL fMCast, SOCKADDR_IN * psockAddrInRemote)
  64. {
  65. HRESULT hr = S_OK;
  66. if(!FIsSocketValid(sock))
  67. {
  68. delete [] szData;
  69. return S_OK;
  70. }
  71. CReceiveData * pData = new CReceiveData(szData, sock, FALSE, fMCast, psockAddrInRemote);
  72. if(!pData)
  73. {
  74. delete [] szData;
  75. hr = E_OUTOFMEMORY;
  76. }
  77. CLock lock(m_critSec);
  78. if(SUCCEEDED(hr))
  79. {
  80. if(!m_pHead)
  81. {
  82. m_pHead = m_pTail = pData;
  83. }
  84. else
  85. {
  86. m_pTail->m_pNext = pData;
  87. m_pTail = pData;
  88. }
  89. SetEvent(m_hEventWork);
  90. }
  91. TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CReceiveDataManager::HrAddData");
  92. return hr;
  93. }
  94. HRESULT CReceiveDataManager::HrInitialize()
  95. {
  96. HRESULT hr = S_OK;
  97. m_hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
  98. if(!m_hEventShutdown)
  99. {
  100. hr = HrFromLastWin32Error();
  101. }
  102. if(SUCCEEDED(hr))
  103. {
  104. m_hEventWork = CreateEvent(NULL, TRUE, FALSE, NULL);
  105. if(!m_hEventWork)
  106. {
  107. hr = HrFromLastWin32Error();
  108. }
  109. if(SUCCEEDED(hr))
  110. {
  111. m_hThread = CreateThread(NULL, 0, &CReceiveDataManager::ThreadFunc, NULL, 0, NULL);
  112. if(!m_hThread)
  113. {
  114. hr = HrFromLastWin32Error();
  115. }
  116. }
  117. }
  118. TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CReceiveDataManager::HrInitialize");
  119. return hr;
  120. }
  121. HRESULT CReceiveDataManager::HrShutdown()
  122. {
  123. HRESULT hr = S_OK;
  124. if(m_hThread)
  125. {
  126. if(!SetEvent(m_hEventShutdown))
  127. {
  128. }
  129. if(SUCCEEDED(hr))
  130. {
  131. WaitForSingleObject(m_hThread, INFINITE);
  132. CloseHandle(m_hThread);
  133. m_hThread = NULL;
  134. }
  135. }
  136. TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CReceiveDataManager::HrShutdown");
  137. return hr;
  138. }
  139. DWORD WINAPI CReceiveDataManager::ThreadFunc(void *)
  140. {
  141. return CReceiveDataManager::Instance().ThreadMember();
  142. }
  143. DWORD CReceiveDataManager::ThreadMember()
  144. {
  145. HANDLE arHandles[] = {m_hEventWork, m_hEventShutdown};
  146. while(true)
  147. {
  148. DWORD dwRet = WaitForMultipleObjects(2, arHandles, FALSE, INFINITE);
  149. if(WAIT_OBJECT_0 != dwRet)
  150. {
  151. break;
  152. }
  153. while(true)
  154. {
  155. // Get lock and fetch one item
  156. CReceiveData * pData = NULL;
  157. {
  158. CLock lock(m_critSec);
  159. if(m_pHead)
  160. {
  161. pData = m_pHead;
  162. m_pHead = m_pHead->m_pNext;
  163. if(!m_pHead)
  164. {
  165. m_pTail = NULL;
  166. }
  167. }
  168. }
  169. if(!pData)
  170. {
  171. break;
  172. }
  173. // Process data
  174. ProcessReceiveBuffer(pData);
  175. delete pData;
  176. }
  177. ResetEvent(m_hEventWork);
  178. }
  179. return 0;
  180. }
  181. void CReceiveDataManager::ProcessReceiveBuffer(CReceiveData * pData)
  182. {
  183. SSDP_REQUEST ssdpRequest;
  184. RECEIVE_DATA rd;
  185. rd.RemoteSocket = pData->m_sockAddrInRemote;
  186. rd.socket = pData->m_sock;
  187. rd.szBuffer = pData->m_szData;
  188. rd.fIsTcpSocket = pData->m_fIsTcpSocket;
  189. rd.fMCast = pData->m_fMCast;
  190. if(InitializeSsdpRequest(&ssdpRequest))
  191. {
  192. if(ParseSsdpRequest(pData->m_szData, &ssdpRequest))
  193. {
  194. ProcessSsdpRequest(&ssdpRequest, &rd);
  195. }
  196. else
  197. {
  198. FreeSsdpRequest(&ssdpRequest);
  199. }
  200. }
  201. }