#include "PrepDownloadCtrl.h" #include "PatchClient.h" #include "GSEGuard.h" #include #define IDLE_STANDARD 90 CPrepDownloadCtrl::CPrepDownloadCtrl(CPatchClient& PatchClient) : m_PatchClient(PatchClient) { m_hQuery = NULL; PDH_STATUS ps = PdhOpenQuery(NULL, NULL, &m_hQuery); if (ps != ERROR_SUCCESS) { //报告错误 } m_Controls.clear(); m_Thread = NULL; m_Quit = false; m_IdleTime = 0; m_NetworkIntf = GetNetworkIntf(); //获取当前带宽 AddCtrl(BANDWIDTH_MASK, 0); IsInCtrl(); RemoveCtrl(BANDWIDTH_MASK); } CPrepDownloadCtrl::~CPrepDownloadCtrl(void) { for (size_t nIndex = 0; nIndex < m_Counters.size(); nIndex++) { PdhRemoveCounter(m_Counters[nIndex].second); } if (m_hQuery) { PdhCloseQuery(m_hQuery); m_hQuery = NULL; } m_Controls.clear(); } int CPrepDownloadCtrl::AddCtrl(CONTROL_MASK mask, int nMaskValue) { CONTROL_PAIR ctrlPair = make_pair(mask, nMaskValue); GSEGuard gseGuard(&m_Lock); vector::iterator Ite_Mask = ::find(m_Controls.begin(), m_Controls.end(), ctrlPair); if (Ite_Mask == m_Controls.end()) { m_Controls.push_back(ctrlPair); CONTROL_COUNTER ctrlCounter = make_pair(mask, AddControlCounter(mask)); if (ctrlCounter.second != 0) { m_Counters.push_back(ctrlCounter); } } else { Ite_Mask->second = nMaskValue; } return 0; } int CPrepDownloadCtrl::RemoveCtrl(CONTROL_MASK mask) { GSEGuard gseGuard(&m_Lock); for (size_t nIndex = 0; nIndex < m_Controls.size(); nIndex++) { if (m_Controls[nIndex].first == mask) { m_Controls.erase(m_Controls.begin() + nIndex); PdhRemoveCounter(m_Counters[nIndex].second); m_Counters.erase(m_Counters.begin() + nIndex); } } return 0; } bool CPrepDownloadCtrl::IsInCtrl() { bool bRet = true; PdhCollectQueryData(m_hQuery); GSEGuard gseGuard(&m_Lock); for (size_t nIndex = 0; nIndex < m_Controls.size(); nIndex++) { bRet = bRet && ProcMask(nIndex); } return bRet; } bool CPrepDownloadCtrl::ProcMask(int nIndex) { bool bRet = false; PDH_STATUS ps; PDH_FMT_COUNTERVALUE pfc; DWORD dwOpt; ps = PdhGetFormattedCounterValue(m_Counters[nIndex].second, PDH_FMT_DOUBLE, &dwOpt, &pfc); if (ps == ERROR_SUCCESS) { int nValue = (int)pfc.doubleValue; switch(m_Controls[nIndex].first) { case CPU_MASK: { bRet = nValue > m_Controls[nIndex].second; } break; case NETWORK_MASK: { bRet = nValue > (int)(m_Controls[nIndex].second * m_CurBandWidth / 100.00f); } break; case BANDWIDTH_MASK: { m_CurBandWidth = nValue; } break; case IDLE_MASK: { if (nValue >= IDLE_STANDARD) { if (m_IdleTime != 0) { bRet = (GetTickCount() - m_IdleTime) >= m_Controls[nIndex].second * 60 * 1000; } else { m_IdleTime = GetTickCount(); } } else { m_IdleTime = 0; } } break; default: break; } } else { } return bRet; } PDH_HCOUNTER CPrepDownloadCtrl::AddControlCounter(CONTROL_MASK mask) { //构造性能计数器路径 PDH_COUNTER_PATH_ELEMENTS pcpe; memset(&pcpe, 0, sizeof(pcpe)); switch(mask) { case CPU_MASK: { pcpe.szObjectName = "Processor"; pcpe.szInstanceName = "_Total"; pcpe.szCounterName = "% Processor Time"; pcpe.dwInstanceIndex = -1; } break; case NETWORK_MASK: { pcpe.szObjectName = "Network Interface"; pcpe.szInstanceName = const_cast(m_NetworkIntf.c_str()); pcpe.szCounterName = "Bytes Total/sec"; pcpe.dwInstanceIndex = -1; } break; case IDLE_MASK: { pcpe.szObjectName = "Processor"; pcpe.szInstanceName = "_Total"; pcpe.szCounterName = "% Idle Time"; pcpe.dwInstanceIndex = -1; } break; case BANDWIDTH_MASK: { pcpe.szObjectName = "Network Interface"; pcpe.szInstanceName = const_cast(m_NetworkIntf.c_str()); pcpe.szCounterName = "Current Bandwidth"; pcpe.dwInstanceIndex = -1; } break; default: break; } char szFullPatchBuf[MAX_PATH]; szFullPatchBuf[0] = 0; DWORD dwBufSize = sizeof(szFullPatchBuf); PDH_STATUS ps = PdhMakeCounterPath(&pcpe, szFullPatchBuf, &dwBufSize, 0); if (ps != ERROR_SUCCESS) { return 0; } //添加计数器 PDH_HCOUNTER hCounter; ps = PdhAddCounter(m_hQuery, szFullPatchBuf, 0, &hCounter); if (ps != ERROR_SUCCESS) { return 0; } return hCounter; } void CPrepDownloadCtrl::ThreadProc() { while (!m_Quit) { m_PatchClient.OnControl(IsInCtrl()); Sleep(1000); } } void CPrepDownloadCtrl::Terminate() { } string CPrepDownloadCtrl::GetNetworkIntf() { string strNetDesc; PDH_STATUS ps; char* szCounterList = NULL; DWORD dwCounterSize = 0; char* szInstanceList = NULL; DWORD dwInstanceSize = 0; ps = PdhEnumObjectItems(NULL, NULL, "Network Interface", szCounterList, &dwCounterSize, szInstanceList, &dwInstanceSize, PERF_DETAIL_WIZARD, 0); if (ps == PDH_MORE_DATA) { szCounterList = new char[dwCounterSize]; szInstanceList = new char[dwInstanceSize]; ps = PdhEnumObjectItems(NULL, NULL, "Network Interface", szCounterList, &dwCounterSize, szInstanceList, &dwInstanceSize, PERF_DETAIL_WIZARD, 0); if (ps == ERROR_SUCCESS) { for (char* szInstance = szInstanceList; *szInstance != 0; szInstance += strlen(szInstance) + 1) { if (strcmp(szInstance, "MS TCP Loopback interface")) { strNetDesc = szInstance; break; } } } delete [] szCounterList; delete [] szInstanceList; } return strNetDesc; } int CPrepDownloadCtrl::Start() { m_Quit = false; m_IdleTime = 0; m_Thread = GSECreateThread(this, false); return 0; } int CPrepDownloadCtrl::Stop() { m_Quit = true; GSEDestroyThread(m_Thread); m_Thread = NULL; return 0; }