702 lines
17 KiB
C++
702 lines
17 KiB
C++
|
// Connection.cpp: implementation of the CConnection class.
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "ConnMgr.h"
|
||
|
#include "Connection.h"
|
||
|
#include "Ping.h"
|
||
|
|
||
|
#include <process.h>
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[]=__FILE__;
|
||
|
#define new DEBUG_NEW
|
||
|
#endif
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// CConnection
|
||
|
|
||
|
IMPLEMENT_DYNCREATE(CConnection,CObject)
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Construction/Destruction
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
CConnection::CConnection(BSTR bsMachineName, IWbemLocator* pIWbemLocator)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::CConnection()\n"));
|
||
|
ASSERT(pIWbemLocator);
|
||
|
|
||
|
Init();
|
||
|
m_bsMachineName = SysAllocString(bsMachineName);
|
||
|
m_sNamespace.Format(_T("\\\\%s\\root\\cimv2\\MicrosoftHealthmonitor"),bsMachineName);
|
||
|
m_pIWbemLocator = pIWbemLocator;
|
||
|
m_pIWbemLocator->AddRef();
|
||
|
|
||
|
StartMonitor();
|
||
|
}
|
||
|
|
||
|
CConnection::CConnection()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::CConnection()\n"));
|
||
|
|
||
|
Init();
|
||
|
}
|
||
|
|
||
|
CConnection::~CConnection()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::~CConnection()\n"));
|
||
|
// stop monitoring
|
||
|
StopMonitor();
|
||
|
|
||
|
RemoveAllEventEntries();
|
||
|
|
||
|
if( m_pIWbemServices )
|
||
|
{
|
||
|
if (m_bAvailable)
|
||
|
m_pIWbemServices->Release();
|
||
|
m_pIWbemServices = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_pIWbemLocator)
|
||
|
{
|
||
|
if (m_bAvailable)
|
||
|
m_pIWbemLocator->Release();
|
||
|
m_pIWbemLocator = NULL;
|
||
|
}
|
||
|
|
||
|
SysFreeString(m_bsMachineName);
|
||
|
|
||
|
CloseHandle(m_threadData.m_hDie);
|
||
|
CloseHandle(m_threadData.m_hDead);
|
||
|
|
||
|
// zzz
|
||
|
CloseHandle(m_hReadyToConnect);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Initialize CConnection data members.
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
void CConnection::Init()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::Init()\n"));
|
||
|
m_bAvailable = false;
|
||
|
m_bFirstConnect = true;
|
||
|
m_pIWbemServices = NULL;
|
||
|
m_pIWbemLocator = NULL;
|
||
|
m_dwPollInterval = 10000;
|
||
|
m_bsMachineName = NULL;
|
||
|
|
||
|
m_threadData.m_hDie = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
|
m_threadData.m_hDead = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
|
m_hrLastConnectResult = S_OK;
|
||
|
|
||
|
//zzz
|
||
|
m_hReadyToConnect = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Start/Stop Monitoring connection
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
void CConnection::StartMonitor()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::StartMonitor()\n"));
|
||
|
|
||
|
m_threadData.m_bkptr = this;
|
||
|
m_hThread = (HANDLE)_beginthreadex( NULL,
|
||
|
0,
|
||
|
MonitorConnection,
|
||
|
&m_threadData,
|
||
|
0,
|
||
|
&m_threadID );
|
||
|
if (!m_hThread)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::StartMonitor() Error on _beginthreadex\n"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CConnection::StopMonitor()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::StopMonitor()\n"));
|
||
|
|
||
|
// tell it to die now.
|
||
|
SetEvent(m_threadData.m_hDie);
|
||
|
|
||
|
// if connection is down just kill it.
|
||
|
if (!m_bAvailable)
|
||
|
{
|
||
|
TerminateThread(m_hThread, 0);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// otherwise, give it a chance to die.
|
||
|
if (WAIT_TIMEOUT ==
|
||
|
WaitForSingleObject(m_threadData.m_hDead, m_dwPollInterval))
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::StartMonitor() Timed out - Killing thread.\n"));
|
||
|
TerminateThread(m_hThread, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Thread Func: Establish initial connection and check status.
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
unsigned int __stdcall CConnection::MonitorConnection(void *pv)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::MonitorNode() New Thread!\n"));
|
||
|
|
||
|
struct threadData* pData = (struct threadData*)pv;
|
||
|
|
||
|
HRESULT hRes = pData->m_bkptr->Connect(); // Try to connect first.
|
||
|
if (FAILED(hRes))
|
||
|
pData->m_bkptr->NotifyConsole(hRes);
|
||
|
|
||
|
while (true)
|
||
|
{
|
||
|
if (WAIT_OBJECT_0 == WaitForSingleObject(pData->m_hDie,
|
||
|
pData->m_bkptr->m_dwPollInterval) )
|
||
|
{
|
||
|
SetEvent(pData->m_hDead);
|
||
|
break;
|
||
|
}
|
||
|
// Monitor Managed Node
|
||
|
pData->m_bkptr->CheckConnection();
|
||
|
}
|
||
|
|
||
|
_endthreadex(0);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Check connection status
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
void CConnection::CheckConnection()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::CheckNode()\n"));
|
||
|
|
||
|
if (m_bAvailable) // Connection is available
|
||
|
{ // Check to see it is still valid.
|
||
|
if (!PingMachine())
|
||
|
{ // Connection went down!
|
||
|
OutputDebugString(_T("CConnection::CheckConnection()-Lost connection!\n"));
|
||
|
m_hrLastConnectResult = WBEM_E_TRANSPORT_FAILURE;
|
||
|
SetConnectionStatus(false);
|
||
|
NotifyConsole(m_hrLastConnectResult);
|
||
|
return;
|
||
|
}
|
||
|
// Now, check Wbem connection
|
||
|
m_hrLastConnectResult = m_pIWbemServices->GetObject(0L,0L,0L,0L,0L);
|
||
|
if (FAILED(m_hrLastConnectResult))
|
||
|
{
|
||
|
// Wbem connection is no longer valid!
|
||
|
OutputDebugString(_T("CConnection::CheckConnection()-Lost wbem connection!\n"));
|
||
|
SetConnectionStatus(false);
|
||
|
NotifyConsole(m_hrLastConnectResult);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Try to re-establish connection
|
||
|
Connect();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Connection operations
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CConnection::Connect()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::Connect()\n"));
|
||
|
|
||
|
// zzz
|
||
|
WaitForSingleObject(m_hReadyToConnect, INFINITE);
|
||
|
|
||
|
m_hrLastConnectResult = WBEM_E_TRANSPORT_FAILURE;
|
||
|
|
||
|
// can it be reached?
|
||
|
if (!PingMachine())
|
||
|
return m_hrLastConnectResult;
|
||
|
|
||
|
// now, try to connect to namespace
|
||
|
m_hrLastConnectResult = ConnectToNamespace();
|
||
|
|
||
|
if (FAILED(m_hrLastConnectResult))
|
||
|
return m_hrLastConnectResult;
|
||
|
|
||
|
// is agent ready?
|
||
|
if (FAILED(m_hrLastConnectResult = IsAgentReady()))
|
||
|
return m_hrLastConnectResult;
|
||
|
|
||
|
// is agent correct version ?
|
||
|
if( FAILED(m_hrLastConnectResult = IsAgentCorrectVersion()) )
|
||
|
return m_hrLastConnectResult;
|
||
|
|
||
|
UnRegisterAllEvents();
|
||
|
if (SUCCEEDED(m_hrLastConnectResult = RegisterAllEvents()))
|
||
|
{
|
||
|
SetConnectionStatus(true);
|
||
|
NotifyConsole(m_hrLastConnectResult);
|
||
|
}
|
||
|
|
||
|
return m_hrLastConnectResult;
|
||
|
}
|
||
|
|
||
|
inline HRESULT CConnection::IsAgentReady()
|
||
|
{
|
||
|
// check to see if agent providers are ready to service external requests.
|
||
|
if (!m_pIWbemServices)
|
||
|
return WBEM_E_TRANSPORT_FAILURE;
|
||
|
|
||
|
IEnumWbemClassObject* pEnumObj = NULL;
|
||
|
// HMSystemStatus ready?
|
||
|
BSTR bsName = SysAllocString(L"Microsoft_HMSystemStatus");
|
||
|
HRESULT hRes = m_pIWbemServices->CreateInstanceEnum(bsName,
|
||
|
WBEM_FLAG_SHALLOW,
|
||
|
NULL,
|
||
|
&pEnumObj);
|
||
|
SysFreeString(bsName);
|
||
|
|
||
|
if (FAILED(hRes))
|
||
|
{
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentReady()-Agent is unavailable to deliver SystemStatus on %s. Operation failed with result=<%X>."), CString(m_bsMachineName), hRes);
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
|
||
|
/*
|
||
|
// HMCatStatus ready?
|
||
|
SysReAllocString(&bsName, L"HMCatStatus");
|
||
|
hRes = m_pIWbemServices->CreateInstanceEnum(bsName,
|
||
|
WBEM_FLAG_SHALLOW,
|
||
|
NULL,
|
||
|
&pEnumObj);
|
||
|
SysFreeString(bsName);
|
||
|
|
||
|
if (FAILED(hRes))
|
||
|
return hRes;
|
||
|
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
|
||
|
// HMMachStatus ready?
|
||
|
SysReAllocString(&bsName, L"HMMachStatus");
|
||
|
hRes = m_pIWbemServices->CreateInstanceEnum(bsName,
|
||
|
WBEM_FLAG_SHALLOW,
|
||
|
NULL,
|
||
|
&pEnumObj);
|
||
|
SysFreeString(bsName);
|
||
|
|
||
|
if (FAILED(hRes))
|
||
|
return hRes;
|
||
|
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
*/
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
inline HRESULT CConnection::IsAgentCorrectVersion()
|
||
|
{
|
||
|
// check to see if agent is correct version to service external requests.
|
||
|
if (!m_pIWbemServices)
|
||
|
return WBEM_E_TRANSPORT_FAILURE;
|
||
|
|
||
|
IEnumWbemClassObject* pEnumObj = NULL;
|
||
|
|
||
|
// HMVersion check
|
||
|
|
||
|
// enumerate for HMVersion
|
||
|
BSTR bsName = SysAllocString(L"Microsoft_HMVersion");
|
||
|
HRESULT hRes = m_pIWbemServices->CreateInstanceEnum(bsName,
|
||
|
WBEM_FLAG_SHALLOW,
|
||
|
NULL,
|
||
|
&pEnumObj);
|
||
|
SysFreeString(bsName);
|
||
|
|
||
|
if (FAILED(hRes))
|
||
|
{
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentCorrectVersion()-Unable to enumerate for Microsoft_HMVersion on system %s. Operation failed with result=<%X>."), CString(m_bsMachineName), hRes);
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
IWbemClassObject* pObject = NULL;
|
||
|
ULONG uReturned = 0L;
|
||
|
|
||
|
hRes = pEnumObj->Next(WBEM_INFINITE,1,&pObject,&uReturned);
|
||
|
if( FAILED(hRes) || uReturned == 0L )
|
||
|
{
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentCorrectVersion()-Unable to enumerate for Microsoft_HMVersion on system %s. Operation failed with result=<%X>.\n"), CString(m_bsMachineName), hRes);
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
VARIANT vPropValue;
|
||
|
VariantInit(&vPropValue);
|
||
|
|
||
|
bsName = SysAllocString(L"MajorVersion");
|
||
|
|
||
|
hRes = pObject->Get(bsName, 0L, &vPropValue, NULL, NULL);
|
||
|
|
||
|
SysFreeString(bsName);
|
||
|
|
||
|
if( FAILED(hRes) )
|
||
|
{
|
||
|
pObject->Release();
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentCorrectVersion()-Unable to enumerate for Microsoft_HMVersion on system %s. Operation failed with result=<%X>.\n"), CString(m_bsMachineName), hRes);
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
CString sMajorVersion = V_BSTR(&vPropValue);
|
||
|
|
||
|
VariantClear(&vPropValue);
|
||
|
|
||
|
if( _ttoi(sMajorVersion) != SCHEMA_MAJOR_VERSION )
|
||
|
{
|
||
|
pObject->Release();
|
||
|
pEnumObj->Release();
|
||
|
hRes = E_NOTIMPL;
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentCorrectVersion()-Incorrect Agent version number on system %s.\n"), CString(m_bsMachineName));
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
VariantInit(&vPropValue);
|
||
|
|
||
|
bsName = SysAllocString(L"MinorVersion");
|
||
|
|
||
|
hRes = pObject->Get(bsName, 0L, &vPropValue, NULL, NULL);
|
||
|
|
||
|
SysFreeString(bsName);
|
||
|
|
||
|
if( FAILED(hRes) )
|
||
|
{
|
||
|
pObject->Release();
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentCorrectVersion()-Incorrect Agent version number on system %s.\n"), CString(m_bsMachineName));
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
CString sMinorVersion = V_BSTR(&vPropValue);
|
||
|
|
||
|
VariantClear(&vPropValue);
|
||
|
|
||
|
if( _ttoi(sMinorVersion) != SCHEMA_MINOR_VERSION )
|
||
|
{
|
||
|
pObject->Release();
|
||
|
pEnumObj->Release();
|
||
|
hRes = E_NOTIMPL;
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("IsAgentCorrectVersion()-Incorrect Agent version number on system %s.\n"), CString(m_bsMachineName));
|
||
|
OutputDebugString(sDebugString);
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
pObject->Release();
|
||
|
pEnumObj->Release();
|
||
|
pEnumObj = NULL;
|
||
|
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
inline void CConnection::SetConnectionStatus(BOOL bFlag)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::SetConnectionStatus()\n"));
|
||
|
if (m_bAvailable != bFlag)
|
||
|
{
|
||
|
m_bAvailable = bFlag;
|
||
|
}
|
||
|
else
|
||
|
OutputDebugString(_T("CConnection::SetConnectionStatus()-No change in Connection Status!\n"));
|
||
|
}
|
||
|
|
||
|
inline BOOL CConnection::PingMachine()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::Ping()\n"));
|
||
|
CPing Pong;
|
||
|
unsigned long ulIP = Pong.ResolveName(m_bsMachineName);
|
||
|
if (!Pong.Ping(ulIP,999))
|
||
|
{
|
||
|
CString sDebugString;
|
||
|
sDebugString.Format(_T("PingMachine() failed on system %s.\n"), CString(m_bsMachineName));
|
||
|
OutputDebugString(sDebugString);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Namespace operations
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
inline HRESULT CConnection::ConnectToNamespace(BSTR bsNamespace /*= NULL*/)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::ConnectToNamespace()\n"));
|
||
|
|
||
|
if (m_pIWbemServices)
|
||
|
{
|
||
|
m_pIWbemServices->Release();
|
||
|
// m_pIWbemServices = NULL();
|
||
|
m_pIWbemServices = NULL;
|
||
|
}
|
||
|
|
||
|
HRESULT hRes;
|
||
|
if( ! bsNamespace )
|
||
|
{
|
||
|
bsNamespace = m_sNamespace.AllocSysString();
|
||
|
hRes = m_pIWbemLocator->ConnectServer(bsNamespace,0L,0L,0L,0L,0L,0L,&m_pIWbemServices);
|
||
|
::SysFreeString(bsNamespace);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hRes = m_pIWbemLocator->ConnectServer(bsNamespace,0L,0L,0L,0L,0L,0L,&m_pIWbemServices);
|
||
|
}
|
||
|
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Event Operations
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
BOOL CConnection::AddEventEntry(const CString& sQuery, IWbemObjectSink*& pSink)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::AddEventEntry()\n"));
|
||
|
|
||
|
ASSERT(pSink);
|
||
|
if( pSink == NULL )
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::AddEventEntry()-pSink is NULL. Failed.\n"));
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
ASSERT(!sQuery.IsEmpty());
|
||
|
if( sQuery.IsEmpty() )
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::AddEventEntry()-The query string passed is empty. Failed.\n"));
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// do not add duplicate event entry.
|
||
|
for (int i = 0; i < m_EventConsumers.GetSize(); i++)
|
||
|
{
|
||
|
if (pSink == m_EventConsumers[i]->m_pSink &&
|
||
|
sQuery == m_EventConsumers[i]->m_sQuery)
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
CEventRegistrationEntry* pEntry = new CEventRegistrationEntry(sQuery, pSink);
|
||
|
m_EventConsumers.Add(pEntry);
|
||
|
|
||
|
if( m_bAvailable )
|
||
|
{
|
||
|
BSTR bsLang = SysAllocString(L"WQL");
|
||
|
BSTR bsQuery = pEntry->m_sQuery.AllocSysString();
|
||
|
|
||
|
HRESULT hr = m_pIWbemServices->ExecNotificationQueryAsync(bsLang,
|
||
|
bsQuery,
|
||
|
0L,
|
||
|
0L,
|
||
|
pEntry->m_pSink);
|
||
|
::SysFreeString(bsQuery);
|
||
|
::SysFreeString(bsLang);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
pEntry->m_bRegistered = true;
|
||
|
}
|
||
|
|
||
|
// zzz
|
||
|
SetEvent(m_hReadyToConnect);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
BOOL CConnection::RemoveEventEntry(IWbemObjectSink*& pSink)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::RemoveEventEntry()\n"));
|
||
|
for( int i=0; i < m_EventConsumers.GetSize(); i++ )
|
||
|
{
|
||
|
if( pSink == m_EventConsumers[i]->m_pSink )
|
||
|
{
|
||
|
CEventRegistrationEntry* pEntry = m_EventConsumers[i];
|
||
|
ASSERT(pEntry);
|
||
|
ASSERT_VALID(pEntry);
|
||
|
|
||
|
if (pEntry->m_bRegistered && m_pIWbemServices && m_bAvailable)
|
||
|
{
|
||
|
if (SUCCEEDED(m_pIWbemServices->CancelAsyncCall(pEntry->m_pSink)))
|
||
|
pEntry->m_bRegistered = false;
|
||
|
}
|
||
|
delete pEntry;
|
||
|
m_EventConsumers.RemoveAt(i);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CConnection::RemoveAllEventEntries()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::RemoveAllEventEntries()\n"));
|
||
|
HRESULT hr;
|
||
|
for (int i=0; i < m_EventConsumers.GetSize(); i++)
|
||
|
{
|
||
|
CEventRegistrationEntry* pEntry = m_EventConsumers[i];
|
||
|
ASSERT(pEntry);
|
||
|
ASSERT_VALID(pEntry);
|
||
|
|
||
|
if (pEntry->m_bRegistered && m_pIWbemServices && m_bAvailable)
|
||
|
hr = m_pIWbemServices->CancelAsyncCall(pEntry->m_pSink);
|
||
|
|
||
|
delete pEntry;
|
||
|
}
|
||
|
m_EventConsumers.RemoveAll();
|
||
|
}
|
||
|
|
||
|
HRESULT CConnection::RegisterAllEvents()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::RegisterAllEvents()\n"));
|
||
|
|
||
|
// if there's no sink, return server too busy.
|
||
|
if (!m_EventConsumers.GetSize())
|
||
|
return WBEM_E_SERVER_TOO_BUSY;
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
int i = 0;
|
||
|
BSTR bsLang = SysAllocString(L"WQL");
|
||
|
for(i=0; i < m_EventConsumers.GetSize(); i++)
|
||
|
{
|
||
|
CEventRegistrationEntry* pEntry = m_EventConsumers[i];
|
||
|
ASSERT(pEntry);
|
||
|
ASSERT_VALID(pEntry);
|
||
|
|
||
|
if( pEntry->m_eType != AsyncQuery )
|
||
|
{
|
||
|
BSTR bsQuery = pEntry->m_sQuery.AllocSysString();
|
||
|
|
||
|
OutputDebugString(_T("\t"));
|
||
|
OutputDebugString(pEntry->m_sQuery);
|
||
|
OutputDebugString(_T("\n"));
|
||
|
|
||
|
hr = m_pIWbemServices->ExecNotificationQueryAsync(bsLang,
|
||
|
bsQuery,
|
||
|
0L,
|
||
|
0L,
|
||
|
pEntry->m_pSink);
|
||
|
::SysFreeString(bsQuery);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
pEntry->m_bRegistered = true;
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pEntry->SendInstances(m_pIWbemServices,2);
|
||
|
m_EventConsumers.RemoveAt(i);
|
||
|
delete pEntry;
|
||
|
}
|
||
|
}
|
||
|
::SysFreeString(bsLang);
|
||
|
// Cancel any succeeded calls????
|
||
|
/*
|
||
|
i--;
|
||
|
if (FAILED(hr) && i >= 0)
|
||
|
{ // cancel succeeded calls
|
||
|
while(i>=0)
|
||
|
{
|
||
|
CEventRegistrationEntry* pEntry = m_EventConsumers[i];
|
||
|
ASSERT(pEntry);
|
||
|
ASSERT_VALID(pEntry);
|
||
|
if (pEntry->m_bRegistered)
|
||
|
{
|
||
|
HRESULT hRes = m_pIWbemServices->CancelAsyncCall(pEntry->m_pSink);
|
||
|
pEntry->m_bRegistered = false;
|
||
|
}
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
void CConnection::UnRegisterAllEvents()
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::UnRegisterAllEvents()\n"));
|
||
|
|
||
|
for (int i=0; i < m_EventConsumers.GetSize(); i++)
|
||
|
{
|
||
|
CEventRegistrationEntry* pEntry = m_EventConsumers[i];
|
||
|
ASSERT(pEntry);
|
||
|
ASSERT_VALID(pEntry);
|
||
|
if (pEntry->m_bRegistered && pEntry->m_eType != AsyncQuery )
|
||
|
{
|
||
|
HRESULT hr = m_pIWbemServices->CancelAsyncCall(pEntry->m_pSink);
|
||
|
pEntry->m_bRegistered = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// Console notification
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
inline HRESULT CConnection::NotifyConsole(HRESULT hRes)
|
||
|
{
|
||
|
OutputDebugString(_T("CConnection::NotifyCosole()\n"));
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
// Set notify flag appropriately
|
||
|
long lFlag = 0;
|
||
|
if (hRes == S_OK)
|
||
|
{
|
||
|
if (m_bFirstConnect)
|
||
|
{
|
||
|
lFlag = 2;
|
||
|
}
|
||
|
else
|
||
|
lFlag = 1;
|
||
|
}
|
||
|
|
||
|
for (int i=0; i < m_EventConsumers.GetSize(); i++)
|
||
|
{
|
||
|
CEventRegistrationEntry* pEntry = m_EventConsumers[i];
|
||
|
ASSERT(pEntry);
|
||
|
ASSERT_VALID(pEntry);
|
||
|
|
||
|
// Notify console w/ connection status
|
||
|
if (i == 0)
|
||
|
hr = pEntry->NotifyConsole(lFlag, hRes);
|
||
|
|
||
|
// If connection is bad, no need to continue
|
||
|
if (hRes != S_OK)
|
||
|
break;
|
||
|
|
||
|
// Reset first connect flag
|
||
|
if (SUCCEEDED(hr) && m_bFirstConnect)
|
||
|
m_bFirstConnect = false;
|
||
|
|
||
|
HRESULT hr2 = pEntry->SendInstances(m_pIWbemServices, lFlag);
|
||
|
}
|
||
|
|
||
|
return hRes;
|
||
|
}
|