538 lines
12 KiB
C++
538 lines
12 KiB
C++
// METHPROV.CPP: implementation of the CBaseMethodProvider class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
#include <atlbase.h>
|
|
#include "HMAgent.h"
|
|
#include "methprov.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// global data
|
|
extern CSystem* g_pSystem;
|
|
extern HANDLE g_hConfigLock;
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CBaseMethodProvider::CBaseMethodProvider()
|
|
{
|
|
OutputDebugString(L"CBaseMethodProvider::CBaseMethodProvider()\n");
|
|
|
|
MY_ASSERT(g_pSystem);
|
|
m_pSystem = g_pSystem;
|
|
|
|
m_cRef = 0L;
|
|
m_pIWbemServices = NULL;
|
|
}
|
|
|
|
CBaseMethodProvider::~CBaseMethodProvider()
|
|
{
|
|
OutputDebugString(L"CBaseMethodProvider::~CBaseMethodProvider()\n");
|
|
|
|
if (m_pIWbemServices)
|
|
{
|
|
m_pIWbemServices->Release();
|
|
}
|
|
|
|
m_pIWbemServices = NULL;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// IUnknown Implementation
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CBaseMethodProvider::QueryInterface(REFIID riid, LPVOID* ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if(riid== IID_IWbemServices)
|
|
{
|
|
*ppv=(IWbemServices*)this;
|
|
}
|
|
|
|
if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
|
|
{
|
|
*ppv=(IWbemProviderInit*)this;
|
|
}
|
|
|
|
|
|
if (NULL!=*ppv)
|
|
{
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CBaseMethodProvider::AddRef(void)
|
|
{
|
|
return InterlockedIncrement((long*)&m_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CBaseMethodProvider::Release(void)
|
|
{
|
|
LONG lCount = InterlockedDecrement((long*)&m_cRef);
|
|
|
|
if (0 != lCount)
|
|
{
|
|
return lCount;
|
|
}
|
|
|
|
delete this;
|
|
return 0L;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// IWbemProviderInit Implementation
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CBaseMethodProvider::Initialize(LPWSTR pszUser,
|
|
LONG lFlags,
|
|
LPWSTR pszNamespace,
|
|
LPWSTR pszLocale,
|
|
IWbemServices __RPC_FAR *pNamespace,
|
|
IWbemContext __RPC_FAR *pCtx,
|
|
IWbemProviderInitSink __RPC_FAR *pInitSink)
|
|
{
|
|
OutputDebugString(L"CBaseMethodProvider::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 CBaseMethodProvider::ExecMethodAsync(const BSTR ObjectPath, const BSTR MethodName,
|
|
long lFlags, IWbemContext* pCtx, IWbemClassObject* pInParams,
|
|
IWbemObjectSink* pResultSink)
|
|
{
|
|
CComVariant var;
|
|
CComVariant v;
|
|
IWbemClassObject * pClass = NULL;
|
|
IWbemClassObject * pOutClass = NULL;
|
|
IWbemClassObject* pOutParams = NULL;
|
|
SAFEARRAY* psa = NULL;
|
|
LPTSTR szOriginalSystem = NULL;
|
|
LPTSTR szOriginalParentGUID = NULL;
|
|
LPTSTR szGUID = NULL;
|
|
DWORD iRetValue;
|
|
HRESULT hRetRes;
|
|
BOOL bForceReplace;
|
|
DWORD dwErr = 0;
|
|
|
|
MY_OUTPUT(L"CBaseMethodProvider::ExecMethodAsync()", 1);
|
|
|
|
//
|
|
// Do some minimal error checking.
|
|
//
|
|
if(MethodName == NULL || pInParams == NULL || pResultSink == NULL)
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!g_pSystem)
|
|
{
|
|
hRetRes=WBEM_E_FAILED;
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = m_pIWbemServices->GetObject(ObjectPath, 0, pCtx, &pClass, NULL);
|
|
if(hRetRes != S_OK)
|
|
{
|
|
MY_HRESASSERT(hRetRes);
|
|
goto error;
|
|
}
|
|
|
|
// Call the appropriate method.
|
|
// retval == 0 means success...
|
|
|
|
// Get the input argument
|
|
hRetRes = pInParams->Get(L"TargetGUID", 0, &var, NULL, NULL);
|
|
MY_HRESASSERT(hRetRes);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
if (V_VT(&var)==VT_NULL)
|
|
{
|
|
hRetRes = WBEM_E_INVALID_PARAMETER;
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = pClass->GetMethod(MethodName, 0, NULL, &pOutClass);
|
|
MY_HRESASSERT(hRetRes);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = pOutClass->SpawnInstance(0, &pOutParams);
|
|
MY_HRESASSERT(hRetRes);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
// now we need to acquire the Mutex, not before!
|
|
MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync 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 CBaseMethodProvider::ExecMethodAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
|
|
|
|
try
|
|
{
|
|
if (!wcscmp(MethodName, L"Delete"))
|
|
{
|
|
hRetRes = m_pSystem->FindAndDeleteByGUID(V_BSTR(&var));
|
|
iRetValue = hRetRes;
|
|
}
|
|
else if (!wcscmp(MethodName, L"ResetAndCheckNow"))
|
|
{
|
|
hRetRes = m_pSystem->FindAndResetDEStateByGUID(V_BSTR(&var));
|
|
iRetValue = hRetRes;
|
|
}
|
|
else if (!wcscmp(MethodName, L"ResetDataCollectorStatistics"))
|
|
{
|
|
hRetRes = m_pSystem->FindAndResetDEStatisticsByGUID(V_BSTR(&var));
|
|
iRetValue = hRetRes;
|
|
}
|
|
else if (!wcscmp(MethodName, L"CopyWithActions"))
|
|
{
|
|
hRetRes = m_pSystem->FindAndCopyWithActionsByGUID(V_BSTR(&var), &psa, &szOriginalParentGUID);
|
|
if (hRetRes==S_OK)
|
|
{
|
|
// This method returns values, and so create an instance of the
|
|
// output argument class.
|
|
|
|
DWORD dwNameLen = MAX_COMPUTERNAME_LENGTH + 1;
|
|
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
|
if (GetComputerName(szComputerName, &dwNameLen))
|
|
{
|
|
hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", szComputerName);
|
|
}
|
|
else
|
|
{
|
|
hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", L"LocalMachine");
|
|
}
|
|
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = PutStrProperty(pOutParams, L"OriginalParentGUID", szOriginalParentGUID);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = PutSAProperty(pOutParams, L"Instances", psa);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
// Don't need to delete this below unless there was an error!
|
|
// We do not free this if we sent it in a Put.
|
|
// Because, we do a VariantClear(&v); inside of PutSAProperty.
|
|
psa = NULL;
|
|
|
|
iRetValue = 0;
|
|
}
|
|
else
|
|
{
|
|
iRetValue = hRetRes;
|
|
MY_OUTPUT(L"failed to get instance!", 1);
|
|
}
|
|
}
|
|
else if (!wcscmp(MethodName, L"PasteWithActions"))
|
|
{
|
|
hRetRes = pInParams->Get(L"Instances", 0L, &v, NULL, NULL);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
if (V_VT(&v)==VT_NULL)
|
|
{
|
|
iRetValue = 1;
|
|
}
|
|
else
|
|
{
|
|
MY_ASSERT(V_VT(&v)==(VT_UNKNOWN|VT_ARRAY));
|
|
hRetRes = GetStrProperty(pInParams, L"OriginalSystem", &szOriginalSystem);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = GetStrProperty(pInParams, L"OriginalParentGUID", &szOriginalParentGUID);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = GetBoolProperty(pInParams, L"ForceReplace", &bForceReplace);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = m_pSystem->FindAndPasteWithActionsByGUID(V_BSTR(&var), v.parray, szOriginalSystem, szOriginalParentGUID, bForceReplace);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
iRetValue = hRetRes;
|
|
|
|
}
|
|
|
|
//
|
|
// Send the output object back to the client via the sink.
|
|
|
|
}
|
|
else if (!wcscmp(MethodName, L"Copy"))
|
|
{
|
|
hRetRes = m_pSystem->FindAndCopyByGUID(V_BSTR(&var), &psa, &szOriginalParentGUID);
|
|
if (hRetRes==S_OK)
|
|
{
|
|
// This method returns values, and so create an instance of the
|
|
// output argument class.
|
|
|
|
DWORD dwNameLen = MAX_COMPUTERNAME_LENGTH + 1;
|
|
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
|
if (GetComputerName(szComputerName, &dwNameLen))
|
|
{
|
|
hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", szComputerName);
|
|
}
|
|
else
|
|
{
|
|
hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", L"LocalMachine");
|
|
}
|
|
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = PutStrProperty(pOutParams, L"OriginalParentGUID", szOriginalParentGUID);
|
|
szOriginalParentGUID = NULL; // Don't need to delete this below, as we are pointing it to something
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = PutSAProperty(pOutParams, L"Instances", psa);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
// Don't need to delete this below unless there was an error!
|
|
// We do not free this if we sent it in a Put.
|
|
// Because, we do a VariantClear(&v); inside of PutSAProperty.
|
|
psa = NULL;
|
|
iRetValue = 0;
|
|
}
|
|
else
|
|
{
|
|
iRetValue = hRetRes;
|
|
szOriginalParentGUID = NULL; // Don't need to delete this below, as we are pointing it to something
|
|
MY_OUTPUT(L"failed to get instance!", 1);
|
|
}
|
|
}
|
|
else if (!wcscmp(MethodName, L"Paste"))
|
|
{
|
|
|
|
|
|
hRetRes = pInParams->Get(L"Instances", 0L, &v, NULL, NULL);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
if (V_VT(&v)==VT_NULL)
|
|
{
|
|
iRetValue = 1;
|
|
}
|
|
else
|
|
{
|
|
MY_ASSERT(V_VT(&v)==(VT_UNKNOWN|VT_ARRAY));
|
|
hRetRes = GetStrProperty(pInParams, L"OriginalSystem", &szOriginalSystem);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = GetStrProperty(pInParams, L"OriginalParentGUID", &szOriginalParentGUID);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if (hRetRes != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = GetBoolProperty(pInParams, L"ForceReplace", &bForceReplace);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = m_pSystem->FindAndPasteByGUID(V_BSTR(&var), v.parray, szOriginalSystem, szOriginalParentGUID, bForceReplace);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
iRetValue = hRetRes;
|
|
|
|
}
|
|
|
|
//
|
|
// Send the output object back to the client via the sink.
|
|
|
|
}
|
|
else if (!_wcsicmp(MethodName, L"Move"))
|
|
{
|
|
|
|
#ifdef SAVE
|
|
hRetRes = GetStrProperty(pInParams, L"TargetParentGUID", &szGUID);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = m_pSystem->Move(V_BSTR(&var), szGUID);
|
|
iRetValue = hRetRes;
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
hRetRes = S_OK;
|
|
iRetValue = hRetRes;
|
|
}
|
|
else if (!wcscmp(MethodName, L"DeleteConfigurationActionAssociation"))
|
|
{
|
|
hRetRes = GetStrProperty(pInParams, L"ActionGUID", &szGUID);
|
|
MY_ASSERT(hRetRes==S_OK);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hRetRes = m_pSystem->DeleteConfigActionAssoc(V_BSTR(&var), szGUID);
|
|
iRetValue = hRetRes;
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
hRetRes = WBEM_E_NOT_SUPPORTED;
|
|
goto error;
|
|
}
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
hRetRes = S_FALSE;
|
|
iRetValue = S_FALSE;
|
|
MY_ASSERT(FALSE);
|
|
}
|
|
|
|
//
|
|
// Set the return value
|
|
//
|
|
VariantClear(&var);
|
|
var.vt = VT_I4;
|
|
var.lVal = iRetValue;
|
|
hRetRes = pOutParams->Put(L"ReturnValue" , 0, &var, 0);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
// Send the output object back to the client via the sink.
|
|
hRetRes = pResultSink->Indicate(1, &pOutParams);
|
|
if(FAILED(hRetRes))
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
error:
|
|
// all done now, set the status
|
|
if(SUCCEEDED(hRetRes))
|
|
{
|
|
pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
|
|
}
|
|
else
|
|
{
|
|
MY_ASSERT(FALSE);
|
|
pResultSink->SetStatus(0,hRetRes,NULL,NULL);
|
|
}
|
|
|
|
if (pClass)
|
|
pClass->Release();
|
|
if (pOutClass)
|
|
pOutClass->Release();
|
|
if (pOutParams)
|
|
pOutParams->Release();
|
|
if (szOriginalSystem)
|
|
delete [] szOriginalSystem;
|
|
if (szOriginalParentGUID)
|
|
delete [] szOriginalParentGUID;
|
|
if (psa)
|
|
{
|
|
MY_ASSERT(FALSE);
|
|
SafeArrayDestroy(psa);
|
|
}
|
|
if (szGUID)
|
|
delete [] szGUID;
|
|
|
|
MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync g_hConfigLock BLOCK - RELEASE IT", 4);
|
|
ReleaseMutex(g_hConfigLock);
|
|
MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync g_hConfigLock BLOCK - RELEASED", 4);
|
|
return hRetRes;
|
|
}
|