|
|
// 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; } }
|