//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000. // // File: R E C E I V E D A T A . C P P // // Contents: Queue of received data from network // // Notes: // // Author: mbend 17 Dec 2000 // //---------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "ReceiveData.h" #include "ssdp.h" #include "status.h" #include "ssdpfunc.h" #include "ssdptypes.h" #include "ssdpnetwork.h" #include "ncbase.h" #include "event.h" #include "ncinet.h" VOID ProcessSsdpRequest(PSSDP_REQUEST pSsdpRequest, RECEIVE_DATA *pData); CReceiveData::CReceiveData(char * szData, SOCKET sock, BOOL fIsTcpSocket, BOOL fMCast, SOCKADDR_IN * psockAddrInRemote) : m_szData(szData), m_pNext(NULL), m_sock(sock), m_fIsTcpSocket(fIsTcpSocket), m_fMCast(fMCast) { m_sockAddrInRemote = *psockAddrInRemote; } CReceiveData::~CReceiveData() { delete [] m_szData; } CReceiveDataManager CReceiveDataManager::s_instance; CReceiveDataManager::CReceiveDataManager() : m_hEventShutdown(NULL), m_hEventWork(NULL), m_hThread(NULL), m_pHead(NULL), m_pTail(NULL) { } CReceiveDataManager::~CReceiveDataManager() { if(m_hEventShutdown) { CloseHandle(m_hEventShutdown); m_hEventShutdown = NULL; } if(m_hEventWork) { CloseHandle(m_hEventWork); m_hEventWork = NULL; } if(m_hThread) { CloseHandle(m_hThread); m_hThread = NULL; } } CReceiveDataManager & CReceiveDataManager::Instance() { return s_instance; } HRESULT CReceiveDataManager::HrAddData(char * szData, SOCKET sock, BOOL fMCast, SOCKADDR_IN * psockAddrInRemote) { HRESULT hr = S_OK; if(!FIsSocketValid(sock)) { delete [] szData; return S_OK; } CReceiveData * pData = new CReceiveData(szData, sock, FALSE, fMCast, psockAddrInRemote); if(!pData) { delete [] szData; hr = E_OUTOFMEMORY; } CLock lock(m_critSec); if(SUCCEEDED(hr)) { if(!m_pHead) { m_pHead = m_pTail = pData; } else { m_pTail->m_pNext = pData; m_pTail = pData; } SetEvent(m_hEventWork); } TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CReceiveDataManager::HrAddData"); return hr; } HRESULT CReceiveDataManager::HrInitialize() { HRESULT hr = S_OK; m_hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL); if(!m_hEventShutdown) { hr = HrFromLastWin32Error(); } if(SUCCEEDED(hr)) { m_hEventWork = CreateEvent(NULL, TRUE, FALSE, NULL); if(!m_hEventWork) { hr = HrFromLastWin32Error(); } if(SUCCEEDED(hr)) { m_hThread = CreateThread(NULL, 0, &CReceiveDataManager::ThreadFunc, NULL, 0, NULL); if(!m_hThread) { hr = HrFromLastWin32Error(); } } } TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CReceiveDataManager::HrInitialize"); return hr; } HRESULT CReceiveDataManager::HrShutdown() { HRESULT hr = S_OK; if(m_hThread) { if(!SetEvent(m_hEventShutdown)) { } if(SUCCEEDED(hr)) { WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); m_hThread = NULL; } } TraceHr(ttidSsdpNetwork, FAL, hr, FALSE, "CReceiveDataManager::HrShutdown"); return hr; } DWORD WINAPI CReceiveDataManager::ThreadFunc(void *) { return CReceiveDataManager::Instance().ThreadMember(); } DWORD CReceiveDataManager::ThreadMember() { HANDLE arHandles[] = {m_hEventWork, m_hEventShutdown}; while(true) { DWORD dwRet = WaitForMultipleObjects(2, arHandles, FALSE, INFINITE); if(WAIT_OBJECT_0 != dwRet) { break; } while(true) { // Get lock and fetch one item CReceiveData * pData = NULL; { CLock lock(m_critSec); if(m_pHead) { pData = m_pHead; m_pHead = m_pHead->m_pNext; if(!m_pHead) { m_pTail = NULL; } } } if(!pData) { break; } // Process data ProcessReceiveBuffer(pData); delete pData; } ResetEvent(m_hEventWork); } return 0; } void CReceiveDataManager::ProcessReceiveBuffer(CReceiveData * pData) { SSDP_REQUEST ssdpRequest; RECEIVE_DATA rd; rd.RemoteSocket = pData->m_sockAddrInRemote; rd.socket = pData->m_sock; rd.szBuffer = pData->m_szData; rd.fIsTcpSocket = pData->m_fIsTcpSocket; rd.fMCast = pData->m_fMCast; if(InitializeSsdpRequest(&ssdpRequest)) { if(ParseSsdpRequest(pData->m_szData, &ssdpRequest)) { ProcessSsdpRequest(&ssdpRequest, &rd); } else { FreeSsdpRequest(&ssdpRequest); } } }