WindowsXP-SP1/admin/hmonitor/hmagent/instprov.cpp
2020-09-30 16:53:49 +02:00

577 lines
17 KiB
C++

// INSTPROV.CPP: implementation of the CBaseInstanceProvider class.
//
//////////////////////////////////////////////////////////////////////
#include "HMAgent.h"
#include "instprov.h"
//////////////////////////////////////////////////////////////////////
// global data
extern CSystem* g_pSystem;
extern HANDLE g_hConfigLock;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBaseInstanceProvider::CBaseInstanceProvider()
{
OutputDebugString(L"CBaseInstanceProvider::CBaseInstanceProvider()\n");
m_cRef = 0L;
m_pIWbemServices = NULL;
}
CBaseInstanceProvider::~CBaseInstanceProvider()
{
OutputDebugString(L"CBaseInstanceProvider::~CBaseInstanceProvider()\n");
if (m_pIWbemServices)
{
m_pIWbemServices->Release();
}
m_pIWbemServices = NULL;
}
//////////////////////////////////////////////////////////////////////
// IUnknown Implementation
//////////////////////////////////////////////////////////////////////
STDMETHODIMP CBaseInstanceProvider::QueryInterface(REFIID riid, LPVOID* ppv)
{
MY_ASSERT(ppv);
*ppv = NULL;
if(riid== IID_IWbemServices)
{
*ppv=(IWbemServices*)this;
}
else if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
{
*ppv=(IWbemProviderInit*)this;
}
else
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CBaseInstanceProvider::AddRef(void)
{
return InterlockedIncrement((long*)&m_cRef);
}
STDMETHODIMP_(ULONG) CBaseInstanceProvider::Release(void)
{
LONG lCount = InterlockedDecrement((long*)&m_cRef);
if (0 != lCount)
{
return lCount;
}
delete this;
return 0L;
}
//////////////////////////////////////////////////////////////////////
// IWbemProviderInit Implementation
//////////////////////////////////////////////////////////////////////
HRESULT CBaseInstanceProvider::Initialize(LPWSTR pszUser,
LONG lFlags,
LPWSTR pszNamespace,
LPWSTR pszLocale,
IWbemServices __RPC_FAR *pNamespace,
IWbemContext __RPC_FAR *pCtx,
IWbemProviderInitSink __RPC_FAR *pInitSink)
{
OutputDebugString(L"CBaseInstanceProvider::Initialize()\n");
if (NULL == pNamespace)
{
return WBEM_E_INVALID_PARAMETER;
}
m_pIWbemServices = pNamespace;
m_pIWbemServices->AddRef();
pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
return WBEM_S_NO_ERROR;
}
//////////////////////////////////////////////////////////////////////
// IWbemService Implementation
//////////////////////////////////////////////////////////////////////
HRESULT CBaseInstanceProvider::CreateInstanceEnumAsync(const BSTR Class, long lFlags,
IWbemContext __RPC_FAR *pCtx, IWbemObjectSink __RPC_FAR *pResponseHandler)
{
HRESULT hRes;
DWORD dwErr = 0;
TCHAR szClass[HM_MAX_PATH];
if (pResponseHandler == NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
if(dwErr != WAIT_OBJECT_0)
{
if(dwErr = WAIT_TIMEOUT)
{
TRACE_MUTEX(L"TIMEOUT MUTEX");
return WBEM_S_TIMEDOUT;
}
else
{
TRACE_MUTEX(L"WaitForSingleObject on Mutex failed");
return WBEM_E_FAILED;
}
}
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
if (!g_pSystem)
{
ReleaseMutex(g_hConfigLock);
return S_FALSE;
}
// Class is a MicrosoftHM_xxx
MY_ASSERT(wcslen(Class) > HM_PREFIX_LEN);
wcsncpy(szClass, Class, HM_MAX_PATH-1);
szClass[HM_MAX_PATH-1] = '\0';
_wcsupr(szClass);
if (!wcscmp(szClass+HM_PREFIX_LEN, L"SYSTEMSTATUS"))
{
hRes = g_pSystem->SendHMSystemStatusInstances(pResponseHandler);
}
else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATAGROUPSTATUS"))
{
hRes = g_pSystem->SendHMDataGroupStatusInstances(pResponseHandler);
}
else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATUS"))
{
hRes = g_pSystem->SendHMDataCollectorStatusInstances(pResponseHandler);
}
else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATACOLLECTORPERINSTANCESTATUS"))
{
hRes = g_pSystem->SendHMDataCollectorPerInstanceStatusInstances(pResponseHandler);
}
else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATISTICS"))
{
hRes = g_pSystem->SendHMDataCollectorStatisticsInstances(pResponseHandler);
}
else if (!wcscmp(szClass+HM_PREFIX_LEN, L"THRESHOLDSTATUS"))
{
hRes = g_pSystem->SendHMThresholdStatusInstances(pResponseHandler);
}
else if (!wcscmp(szClass+HM_PREFIX_LEN, L"ACTIONSTATUS"))
{
hRes = g_pSystem->SendHMActionStatusInstances(pResponseHandler);
}
else
{
// class not supported by this provider
hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_NOT_SUPPORTED;
}
if (FAILED(hRes))
{
OutputDebugString(L"CBaseInstanceProvider SendSMEvents failed!");
pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASED", 4);
return hRes;
}
// Now let caller know it's done.
pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_S_NO_ERROR;
}
HRESULT CBaseInstanceProvider::GetObjectAsync(const BSTR ObjectPath, long lFlags, IWbemContext __RPC_FAR *pCtx,
IWbemObjectSink __RPC_FAR *pResponseHandler)
{
TCHAR szPath[HM_MAX_PATH];
LPTSTR pszGUID;
LPTSTR pszEnd;
HRESULT hRes;
DWORD dwErr = 0;
if (pResponseHandler==NULL || (HM_MAX_PATH-1) < wcslen(ObjectPath))
{
return WBEM_E_INVALID_PARAMETER;
}
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
if(dwErr != WAIT_OBJECT_0)
{
if(dwErr = WAIT_TIMEOUT)
{
TRACE_MUTEX(L"TIMEOUT MUTEX");
return WBEM_S_TIMEDOUT;
}
else
{
MY_OUTPUT(L"WaitForSingleObject on Mutex failed",4);
return WBEM_E_FAILED;
}
}
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
OutputDebugString(L"CBaseInstanceProvider::GetObjectAsync()\n");
if (!g_pSystem)
{
ReleaseMutex(g_hConfigLock);
return S_FALSE;
}
//
// Going to look something like this ->
// MicrosoftHM_DataGroupStatus.GUID="{269EA380-07CA-11d3-8FEB-006097919914}"
//
wcsncpy(szPath, ObjectPath, HM_MAX_PATH-1);
szPath[HM_MAX_PATH-1] = '\0';
_wcsupr(szPath);
pszEnd = wcschr(szPath, '.');
if (pszEnd)
{
*pszEnd = '\0';
pszEnd++;
pszEnd = wcschr(pszEnd, '"');
if (pszEnd)
{
pszEnd++;
pszGUID = pszEnd;
pszEnd = wcschr(pszEnd, '"');
if (pszEnd)
{
*pszEnd = '\0';
}
else
{
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_INVALID_PARAMETER;
}
}
else
{
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_INVALID_PARAMETER;
}
}
else
{
pszEnd = wcschr(szPath, '=');
if (pszEnd)
{
*pszEnd = '\0';
pszEnd++;
if (*pszEnd == '@')
{
pszGUID = pszEnd;
}
else
{
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_INVALID_PARAMETER;
}
}
else
{
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_INVALID_PARAMETER;
}
}
try
{
//
// Now find out which instance type we need to return.
//
if (!wcscmp(szPath+HM_PREFIX_LEN, L"SYSTEMSTATUS"))
{
hRes = g_pSystem->SendHMSystemStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATAGROUPSTATUS"))
{
hRes = g_pSystem->SendHMDataGroupStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATACOLLECTORSTATUS"))
{
hRes = g_pSystem->SendHMDataCollectorStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATACOLLECTORPERINSTANCESTATUS"))
{
hRes = g_pSystem->SendHMDataCollectorPerInstanceStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATACOLLECTORSTATISTICS"))
{
hRes = g_pSystem->SendHMDataCollectorStatisticsInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(szPath+HM_PREFIX_LEN, L"THRESHOLDSTATUS"))
{
hRes = g_pSystem->SendHMThresholdStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(szPath+HM_PREFIX_LEN, L"ACTIONSTATUS"))
{
hRes = g_pSystem->SendHMActionStatusInstance(pResponseHandler, pszGUID);
}
else
{
MY_ASSERT(FALSE);
hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_NOT_SUPPORTED;
}
}
catch (...)
{
hRes = S_FALSE;
MY_ASSERT(FALSE);
}
if (FAILED(hRes))
{
MY_HRESASSERT(hRes);
OutputDebugString(L"CBaseInstanceProvider SendSMEvents failed!");
pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return hRes;
}
// Now let caller know it's done.
pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_S_NO_ERROR;
}
HRESULT CBaseInstanceProvider::ExecQueryAsync(const BSTR QueryLanguage, const BSTR Query, long lFlags,
IWbemContext __RPC_FAR *pCtx, IWbemObjectSink __RPC_FAR *pResponseHandler)
{
TCHAR szQuery[HM_MAX_PATH];
LPTSTR pszClass;
LPTSTR pszGUID;
LPTSTR pszEnd;
HRESULT hRes;
BOOL bCapable;
DWORD dwErr = 0;
if((pResponseHandler == NULL) || (wcslen(Query) > HM_MAX_PATH-1))
{
return WBEM_E_INVALID_PARAMETER;
}
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
if(dwErr != WAIT_OBJECT_0)
{
if(dwErr = WAIT_TIMEOUT)
{
TRACE_MUTEX(L"TIMEOUT MUTEX");
return WBEM_S_TIMEDOUT;
}
else
{
TRACE_MUTEX(L"WaitForSingleObject on Mutex failed");
return WBEM_E_FAILED;
}
}
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
OutputDebugString(L"CBaseInstanceProvider::GetObjectAsync()\n");
if (!g_pSystem)
{
ReleaseMutex(g_hConfigLock);
return S_FALSE;
}
//
// Going to look something like this ->
// select * from MicrosoftHM_DataCollectorstatus where GUID="{X}"
//
wcsncpy(szQuery, Query, HM_MAX_PATH-1);
szQuery[HM_MAX_PATH-1] = '\0';
bCapable = FALSE;
_wcsupr(szQuery);
pszEnd = wcsstr(szQuery, L"FROM");
if (pszEnd)
{
// Get the name of the Class we are being asked to supply instances of
pszEnd += 4;
while (*pszEnd==' ' || *pszEnd=='\t')
{
pszEnd++;
}
pszClass = pszEnd;
while (*pszEnd!=' ' && *pszEnd!='\t' && *pszEnd!='\0' && *pszEnd!='=')
{
pszEnd++;
}
*pszEnd = '\0';
pszEnd++;
//
// Make sure it is something we can handle
//
if (!wcsstr(pszEnd, L"AND") && !wcsstr(pszEnd, L"OR") && (wcsstr(pszEnd, L" GUID") || wcsstr(pszEnd, L"\tGUID")))
{
pszEnd = wcschr(pszEnd, '"');
if (pszEnd)
{
pszEnd++;
pszGUID = pszEnd;
pszEnd = wcschr(pszEnd, '"');
if (pszEnd)
{
*pszEnd = '\0';
bCapable = TRUE;
}
}
}
}
else
{
pszClass = szQuery;
}
if (bCapable)
{
try
{
//
// Now find out which instance type we need to return.
//
if (!wcscmp(pszClass+HM_PREFIX_LEN, L"SYSTEMSTATUS"))
{
hRes = g_pSystem->SendHMSystemStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATAGROUPSTATUS"))
{
hRes = g_pSystem->SendHMDataGroupStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATUS"))
{
hRes = g_pSystem->SendHMDataCollectorStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATACOLLECTORPERINSTANCESTATUS"))
{
hRes = g_pSystem->SendHMDataCollectorPerInstanceStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATISTICS"))
{
hRes = g_pSystem->SendHMDataCollectorStatisticsInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"THRESHOLDSTATUS"))
{
hRes = g_pSystem->SendHMThresholdStatusInstance(pResponseHandler, pszGUID);
}
else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"ACTIONSTATUS"))
{
hRes = g_pSystem->SendHMActionStatusInstance(pResponseHandler, pszGUID);
}
else
{
MY_ASSERT(FALSE);
hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_E_NOT_SUPPORTED;
}
}
catch (...)
{
hRes = S_FALSE;
MY_ASSERT(FALSE);
}
if (FAILED(hRes))
{
// MY_HRESASSERT(hRes);
hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return hRes;
}
// Now let caller know it's done.
hRes = pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return WBEM_S_NO_ERROR;
}
else
{
// Now let caller know it's done.
//XXX pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
// To implement ExecQueryAsync, and have WMI handle query if the query is too
// complicated. The proper way to handle it today is to call
pResponseHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, WBEM_REQUIREMENTS_START_POSTFILTER, 0, NULL);
// And then proceed to enumerate all your instances.
// NOTE!!! Don't need to release the Mutex because it is done inside the call.
hRes = CBaseInstanceProvider::CreateInstanceEnumAsync(pszClass, lFlags, pCtx, pResponseHandler);
// NOTE!!! Don't need to release the Mutex because it is done inside the call.
// OR DO WE. Once for each Wait called.
//XXX
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
ReleaseMutex(g_hConfigLock);
MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
return hRes;
}
}