You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
718 lines
21 KiB
718 lines
21 KiB
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#include <wbemutil.h>
|
|
#include <ArrTempl.h>
|
|
#include <lmaccess.h>
|
|
#include <wbemdisp.h>
|
|
#include "ScriptKiller.h"
|
|
#include <ErrorObj.h>
|
|
#include "script.h"
|
|
#include "ClassFac.h"
|
|
#include <GroupsForUser.h>
|
|
#include <GenUtils.h>
|
|
#include <strsafe.h>
|
|
|
|
#define SCRIPT_PROPNAME_SCRIPT L"ScriptText"
|
|
#define SCRIPT_PROPNAME_FILENAME L"ScriptFilename"
|
|
#define SCRIPT_PROPNAME_ENGINE L"ScriptingEngine"
|
|
#define SCRIPT_PROPNAME_TIMEOUT L"KillTimeout"
|
|
|
|
#define SCRIPT_EVENTNAME L"TargetEvent"
|
|
|
|
// uncomment me to remove the WMI script object
|
|
// #define NO_DISP_CLASS
|
|
|
|
#ifdef HOWARDS_DEBUG_CODE
|
|
#define NO_DISP_CLASS
|
|
#endif // HOWARDS_DEBUG_CODE
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptConsumer::XProvider::FindConsumer(
|
|
IWbemClassObject* pLogicalConsumer,
|
|
IWbemUnboundObjectSink** ppConsumer)
|
|
{
|
|
if (WMIScriptClassFactory::LimitReached())
|
|
return RPC_E_DISCONNECTED;
|
|
|
|
CScriptSink* pSink = new CScriptSink(m_pObject->m_pControl);
|
|
if (!pSink)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
HRESULT hres = pSink->Initialize(pLogicalConsumer);
|
|
if(FAILED(hres))
|
|
{
|
|
delete pSink;
|
|
*ppConsumer = NULL;
|
|
return hres;
|
|
}
|
|
else return pSink->QueryInterface(IID_IWbemUnboundObjectSink,
|
|
(void**)ppConsumer);
|
|
}
|
|
|
|
void* CScriptConsumer::GetInterface(REFIID riid)
|
|
{
|
|
if(riid == IID_IWbemEventConsumerProvider)
|
|
return &m_XProvider;
|
|
else return NULL;
|
|
}
|
|
|
|
class CScriptSite : public IActiveScriptSite, public IActiveScriptSiteWindow
|
|
{
|
|
protected:
|
|
long m_lRef;
|
|
|
|
IDispatch* m_pObject;
|
|
CScriptSink* m_pSink;
|
|
|
|
HRESULT m_hr;
|
|
public:
|
|
CScriptSite(CScriptSink* pSink, IDispatch* pObject);
|
|
~CScriptSite();
|
|
|
|
HRESULT GetScriptHResult()
|
|
{ return m_hr; }
|
|
|
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);
|
|
ULONG STDMETHODCALLTYPE AddRef();
|
|
ULONG STDMETHODCALLTYPE Release();
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetLCID(
|
|
/* [out] */ LCID __RPC_FAR *plcid);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetItemInfo(
|
|
/* [in] */ LPCOLESTR pstrName,
|
|
/* [in] */ DWORD dwReturnMask,
|
|
/* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppiunkItem,
|
|
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppti);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetDocVersionString(
|
|
/* [out] */ BSTR __RPC_FAR *pbstrVersion);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnScriptTerminate(
|
|
/* [in] */ const VARIANT __RPC_FAR *pvarResult,
|
|
/* [in] */ const EXCEPINFO __RPC_FAR *pexcepinfo);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnStateChange(
|
|
/* [in] */ SCRIPTSTATE ssScriptState);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnScriptError(
|
|
/* [in] */ IActiveScriptError __RPC_FAR *pscripterror);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnEnterScript( void);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE OnLeaveScript( void);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetWindow(
|
|
/* [out] */ HWND __RPC_FAR *phwnd);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE EnableModeless(
|
|
/* [in] */ BOOL fEnable);
|
|
|
|
};
|
|
|
|
CScriptSite::CScriptSite(CScriptSink* pSink, IDispatch* pObject) :
|
|
m_lRef(0), m_hr(0)
|
|
{
|
|
m_pSink = pSink;
|
|
m_pSink->AddRef();
|
|
|
|
m_pObject = pObject;
|
|
if(m_pObject)
|
|
m_pObject->AddRef();
|
|
}
|
|
|
|
CScriptSite::~CScriptSite()
|
|
{
|
|
if (m_pObject)
|
|
m_pObject->Release();
|
|
if (m_pSink)
|
|
m_pSink->Release();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::QueryInterface(REFIID riid, void** ppv)
|
|
{
|
|
if(riid == IID_IUnknown || riid == IID_IActiveScriptSite)
|
|
*ppv = (IActiveScriptSite*)this;
|
|
else if(riid == IID_IActiveScriptSiteWindow)
|
|
*ppv = (IActiveScriptSiteWindow*)this;
|
|
else
|
|
return E_NOINTERFACE;
|
|
((IUnknown*)*ppv)->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE CScriptSite::AddRef()
|
|
{
|
|
return InterlockedIncrement(&m_lRef);
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE CScriptSite::Release()
|
|
{
|
|
long lRef = InterlockedDecrement(&m_lRef);
|
|
if(lRef == 0)
|
|
delete this;
|
|
return lRef;
|
|
}
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::GetLCID(
|
|
/* [out] */ LCID __RPC_FAR *plcid)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::GetItemInfo(
|
|
/* [in] */ LPCOLESTR pstrName,
|
|
/* [in] */ DWORD dwReturnMask,
|
|
/* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppiunkItem,
|
|
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppti)
|
|
{
|
|
if(wbem_wcsicmp(pstrName, SCRIPT_EVENTNAME))
|
|
return TYPE_E_ELEMENTNOTFOUND;
|
|
if(ppti)
|
|
*ppti = NULL;
|
|
if(ppiunkItem)
|
|
*ppiunkItem = NULL;
|
|
|
|
if(dwReturnMask & SCRIPTINFO_IUNKNOWN)
|
|
{
|
|
if(ppiunkItem == NULL)
|
|
return E_POINTER;
|
|
m_pObject->QueryInterface(IID_IUnknown, (void**)ppiunkItem);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::GetDocVersionString(
|
|
/* [out] */ BSTR __RPC_FAR *pbstrVersion)
|
|
{ return E_NOTIMPL;}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::OnScriptTerminate(
|
|
/* [in] */ const VARIANT __RPC_FAR *pvarResult,
|
|
/* [in] */ const EXCEPINFO __RPC_FAR *pexcepinfo)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::OnStateChange(
|
|
/* [in] */ SCRIPTSTATE ssScriptState)
|
|
{ return S_OK;}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::OnScriptError(
|
|
/* [in] */ IActiveScriptError __RPC_FAR *pscripterror)
|
|
{
|
|
HRESULT hres;
|
|
EXCEPINFO ei;
|
|
hres = pscripterror->GetExceptionInfo(&ei);
|
|
if(SUCCEEDED(hres))
|
|
{
|
|
if (ei.bstrSource)
|
|
{
|
|
m_pSink->m_wsErrorMessage = ei.bstrSource;
|
|
m_pSink->m_wsErrorMessage += L": ";
|
|
}
|
|
|
|
if (ei.bstrDescription)
|
|
m_pSink->m_wsErrorMessage += ei.bstrDescription;
|
|
else
|
|
m_pSink->m_wsErrorMessage += L"unknown";
|
|
|
|
if ((ei.wCode != 0) && (ei.wCode >= 1000))
|
|
m_hr = WBEM_E_FAILED;
|
|
else
|
|
m_hr = ei.scode;
|
|
}
|
|
|
|
DWORD cookie;
|
|
ULONG lineNo = 0;
|
|
LONG charPos = 0;
|
|
hres = pscripterror->GetSourcePosition(&cookie, &lineNo, &charPos);
|
|
|
|
// we will construct an error message of the form:
|
|
// filename.vbs (3,15)
|
|
if(SUCCEEDED(hres))
|
|
{
|
|
if (m_pSink->m_wsScriptFileName.Length() > 0)
|
|
m_pSink->m_wsErrorLine = m_pSink->m_wsScriptFileName;
|
|
else
|
|
m_pSink->m_wsErrorLine = SCRIPT_PROPNAME_SCRIPT;
|
|
|
|
// if the sprintf fails for some reason, no problem we concat a null sting.
|
|
WCHAR buf[256] = L"\0";
|
|
// experimentation shows that the line/pos appear to be zero based: add one.
|
|
// swprintf(buf, L" (%u,%d)", lineNo +1, charPos +1);
|
|
StringCchPrintfW(buf, 256, L" (%u,%d)", lineNo +1, charPos +1);
|
|
m_pSink->m_wsErrorLine += buf;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::OnEnterScript( void)
|
|
{ return S_OK;}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::OnLeaveScript( void)
|
|
{ return S_OK;}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::GetWindow(
|
|
/* [out] */ HWND __RPC_FAR *phwnd)
|
|
{
|
|
*phwnd = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSite::EnableModeless(
|
|
/* [in] */ BOOL fEnable)
|
|
{return S_OK;}
|
|
|
|
|
|
CScriptSink::~CScriptSink()
|
|
{
|
|
if(m_pEngineFac)
|
|
m_pEngineFac->Release();
|
|
if (m_pErrorObj)
|
|
m_pErrorObj->Release();
|
|
|
|
}
|
|
|
|
HRESULT CScriptSink::Initialize(IWbemClassObject* pLogicalConsumer)
|
|
{
|
|
VARIANT v;
|
|
VariantInit(&v);
|
|
|
|
// this is actually a pointer to a static object
|
|
// if it fails, something is Very, Very Wrong.
|
|
m_pErrorObj = ErrorObj::GetErrorObj();
|
|
if (!m_pErrorObj)
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
|
|
BSTR propName;
|
|
propName = SysAllocString(L"CreatorSID");
|
|
if (!propName)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
CSysFreeMe freeName(propName);
|
|
|
|
if (SUCCEEDED(pLogicalConsumer->Get(propName, 0, &v, NULL, NULL)))
|
|
{
|
|
HRESULT hDebug;
|
|
long ubound;
|
|
hDebug = SafeArrayGetUBound(V_ARRAY(&v), 1, &ubound);
|
|
|
|
PVOID pVoid;
|
|
hDebug = SafeArrayAccessData(V_ARRAY(&v), &pVoid);
|
|
|
|
if(SUCCEEDED(hDebug))
|
|
{
|
|
m_pSidCreator = new BYTE[ubound +1];
|
|
if (m_pSidCreator)
|
|
memcpy(m_pSidCreator, pVoid, ubound + 1);
|
|
else
|
|
{
|
|
SafeArrayUnaccessData(V_ARRAY(&v));
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
SafeArrayUnaccessData(V_ARRAY(&v));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
// Get the information
|
|
// ===================
|
|
|
|
HRESULT hres;
|
|
VariantInit(&v);
|
|
|
|
hres = pLogicalConsumer->Get(SCRIPT_PROPNAME_ENGINE, 0, &v, NULL, NULL);
|
|
if(FAILED(hres) || V_VT(&v) != VT_BSTR)
|
|
{
|
|
m_pErrorObj->ReportError(SCRIPT_PROPNAME_ENGINE, NULL, NULL, WBEM_E_INVALID_PARAMETER, true);
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
WString wsEngine = V_BSTR(&v);
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(SCRIPT_PROPNAME_TIMEOUT, 0, &v, NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
m_dwKillTimeout = V_I4(&v);
|
|
else
|
|
m_dwKillTimeout = 0;
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(SCRIPT_PROPNAME_SCRIPT, 0, &v, NULL, NULL);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
if (V_VT(&v) == VT_BSTR)
|
|
{
|
|
m_wsScript = V_BSTR(&v);
|
|
VariantClear(&v);
|
|
}
|
|
else
|
|
// try the script file name approach
|
|
{
|
|
hres = pLogicalConsumer->Get(SCRIPT_PROPNAME_FILENAME, 0, &v, NULL, NULL);
|
|
if (SUCCEEDED(hres) && (V_VT(&v) == VT_BSTR))
|
|
{
|
|
m_wsScriptFileName = V_BSTR(&v);
|
|
VariantClear(&v);
|
|
}
|
|
else
|
|
{
|
|
m_pErrorObj->ReportError(L"Initialize", L"ScriptText, ScriptFilename", NULL, WBEM_E_ILLEGAL_NULL, true);
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
|
|
// Get the CLSID
|
|
// =============
|
|
CLSID clsid;
|
|
if (wsEngine.Length() == 0)
|
|
hres = WBEM_E_INVALID_PARAMETER;
|
|
else
|
|
hres = CLSIDFromProgID((LPCWSTR)wsEngine, &clsid);
|
|
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Scripting engine '%S' not found: %X\n",
|
|
(LPCWSTR)wsEngine, hres));
|
|
m_pErrorObj->ReportError(L"Initialize", (WCHAR *)wsEngine, NULL, hres, true);
|
|
return hres;
|
|
}
|
|
|
|
hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
|
|
NULL, IID_IClassFactory, (void**)&m_pEngineFac);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to create scripting engine %S: %X\n",
|
|
(LPCWSTR)wsEngine, hres));
|
|
m_pErrorObj->ReportError(L"Initialize", (WCHAR*)wsEngine, NULL, hres, true);
|
|
return hres;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// runs the script contained in the script text
|
|
HRESULT CScriptSink::RunScriptText(IWbemClassObject *pObj)
|
|
{
|
|
HRESULT hres = S_OK;
|
|
|
|
|
|
WMIScriptClassFactory::IncrementScriptsRun();
|
|
|
|
IActiveScript* pScript;
|
|
hres = m_pEngineFac->CreateInstance(NULL, IID_IActiveScript,
|
|
(void**)&pScript);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to create a script. Error code %X\n",
|
|
hres));
|
|
return hres;
|
|
}
|
|
|
|
IActiveScriptParse* pParse;
|
|
hres = pScript->QueryInterface(IID_IActiveScriptParse, (void**)&pParse);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Scripting engine does not support "
|
|
"parsing!\n"));
|
|
pScript->Release();
|
|
return hres;
|
|
}
|
|
|
|
IDispatch* pDObject;
|
|
#ifdef NO_DISP_CLASS
|
|
pDObject = NULL;
|
|
#else
|
|
IBindCtx *pbc = NULL;;
|
|
IMoniker *pMk = NULL;
|
|
ULONG chEaten = 0;
|
|
|
|
if(FAILED(hres = CreateBindCtx(0, &pbc)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to Create IBindCtx: 0x%X\n", hres));
|
|
pScript->Release();
|
|
return hres;
|
|
}
|
|
|
|
if(FAILED(hres = pbc->RegisterObjectParam(L"WmiObject", pObj)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to Register IBindCtx: 0x%X\n", hres));
|
|
pScript->Release();
|
|
return hres;
|
|
}
|
|
|
|
if(FAILED(hres = MkParseDisplayName(pbc, L"winmgmts:", &chEaten, &pMk)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to MkParseDisplayName: 0x%X\n", hres));
|
|
pScript->Release();
|
|
return hres;
|
|
}
|
|
|
|
if(FAILED(hres = pMk->BindToObject(pbc, 0, IID_ISWbemObject, (void **)&pDObject)))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Unable to BindToObject: 0x%X\n", hres));
|
|
pScript->Release();
|
|
return hres;
|
|
}
|
|
|
|
pMk->Release();
|
|
pbc->Release();
|
|
|
|
#endif
|
|
|
|
CScriptSite* pSite = new CScriptSite(this, pDObject);
|
|
pSite->AddRef();
|
|
|
|
#ifndef NO_DISP_CLASS
|
|
if(pDObject) pDObject->Release();
|
|
#endif
|
|
|
|
hres = pScript->SetScriptSite(pSite);
|
|
|
|
hres = pParse->InitNew();
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to initialize script(InitNew): %X\n",
|
|
hres));
|
|
pSite->Release();
|
|
pScript->Release();
|
|
pParse->Release();
|
|
return hres;
|
|
}
|
|
|
|
#ifndef NO_DISP_CLASS
|
|
hres = pScript->AddNamedItem(SCRIPT_EVENTNAME,
|
|
SCRIPTITEM_ISVISIBLE | SCRIPTITEM_NOCODE);
|
|
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to add named item: %X\n", hres));
|
|
pSite->Release();
|
|
pScript->Release();
|
|
pParse->Release();
|
|
return hres;
|
|
}
|
|
#endif
|
|
|
|
EXCEPINFO ei;
|
|
hres = pParse->ParseScriptText(
|
|
(LPCWSTR)m_wsScript,
|
|
NULL, NULL, NULL,
|
|
0, 0, 0, NULL, &ei);
|
|
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to parse script. Error code %X\n"
|
|
"Scripting engine says: %S\n", hres,
|
|
(LPCWSTR)m_wsErrorMessage));
|
|
m_pErrorObj->ReportError(L"ParseScriptText", m_wsErrorLine, m_wsErrorMessage, hres, true);
|
|
pSite->Release();
|
|
pScript->Release();
|
|
pParse->Release();
|
|
return hres;
|
|
}
|
|
pParse->Release();
|
|
|
|
|
|
if (m_dwKillTimeout)
|
|
{
|
|
FILETIME now;
|
|
GetSystemTimeAsFileTime(&now);
|
|
WAYCOOL_FILETIME expires(now);
|
|
expires.AddSeconds(m_dwKillTimeout);
|
|
|
|
SCRIPTTHREADID threadID;
|
|
hres = pScript->GetScriptThreadID(GetCurrentThreadId(), &threadID);
|
|
if (SUCCEEDED(hres))
|
|
g_scriptKillerTimer.ScheduleAssassination(pScript, expires, threadID);
|
|
|
|
/************
|
|
Doing it in the stream. Probably don't need to.
|
|
LPSTREAM pStream;
|
|
if (SUCCEEDED(hres) &&
|
|
SUCCEEDED(CoMarshalInterThreadInterfaceInStream(IID_IActiveScript, pScript, &pStream)))
|
|
{
|
|
g_scriptKillerTimer.ScheduleAssassination(pStream, expires, threadID);
|
|
}
|
|
***************/
|
|
}
|
|
|
|
hres = pScript->SetScriptState(SCRIPTSTATE_CONNECTED);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to execute script. Error code 0x%X\n"
|
|
"Scripting engine says: %S\n", hres,
|
|
(LPCWSTR)m_wsErrorMessage));
|
|
|
|
m_pErrorObj->ReportError(L"SetScriptState(SCRIPTSTATE_CONNECTED)", m_wsErrorLine, m_wsErrorMessage, hres, true);
|
|
}
|
|
else if (FAILED(pSite->GetScriptHResult()))
|
|
{
|
|
hres = pSite->GetScriptHResult();
|
|
ERRORTRACE((LOG_ESS, "Error in script execution. Error code 0x%X\n"
|
|
"Scripting engine says: %S\n", hres,
|
|
(LPCWSTR)m_wsErrorMessage));
|
|
|
|
m_pErrorObj->ReportError(L"SetScriptState(SCRIPTSTATE_CONNECTED)", m_wsErrorLine, m_wsErrorMessage, hres, true);
|
|
|
|
}
|
|
|
|
pScript->Close();
|
|
|
|
pScript->Release();
|
|
pSite->Release();
|
|
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CScriptSink::RunScriptFile(IWbemClassObject *pObj)
|
|
{
|
|
HRESULT hr = WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (m_wsScriptFileName.Length())
|
|
{
|
|
HANDLE hFile = CreateFileW((LPWSTR)m_wsScriptFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD fSize;
|
|
if (0xFFFFFFFF != (fSize = GetFileSize(hFile, &fSize)))
|
|
{
|
|
char* pBuf = new char[fSize +2];
|
|
if (!pBuf)
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
else
|
|
{
|
|
ZeroMemory(pBuf, fSize+2);
|
|
DWORD bitsRead;
|
|
|
|
if (ReadFile(hFile, pBuf, fSize, &bitsRead, NULL))
|
|
{
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
const WCHAR ByteOrderMark = L'\xFEFF';
|
|
// determine whether this is a unicode file
|
|
if (((WCHAR*)pBuf)[0] == ByteOrderMark)
|
|
m_wsScript.BindPtr((WCHAR*)pBuf);
|
|
else
|
|
{
|
|
int length = strlen(pBuf) +1;
|
|
|
|
// not unicode, do the conversion
|
|
WCHAR* pWideBuf = new WCHAR[length];
|
|
if (!pWideBuf)
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
else
|
|
{
|
|
if (!MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, pBuf, length, pWideBuf, length))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Script: cannot convert %s, 0x%08X\n", pBuf, GetLastError()));
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
else
|
|
m_wsScript.BindPtr(pWideBuf);
|
|
}
|
|
|
|
// delete the old buffer - we saved a copy
|
|
delete[] pBuf;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = RunScriptText(pObj);
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Script: Cannot read %S, 0x%X\n", (LPWSTR)m_wsScriptFileName, GetLastError()));
|
|
delete[] pBuf;
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
}
|
|
else
|
|
ERRORTRACE((LOG_ESS, "Script: Cannot Open %S, 0x%X\n", (LPWSTR)m_wsScriptFileName, GetLastError()));
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CScriptSink::XSink::IndicateToConsumer(
|
|
IWbemClassObject* pLogicalConsumer, long lNumObjects,
|
|
IWbemClassObject** apObjects)
|
|
{
|
|
|
|
PSID pSidSystem;
|
|
SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
|
|
|
|
if (AllocateAndInitializeSid(&id, 1,
|
|
SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0,0,0,0,0,0,&pSidSystem))
|
|
{
|
|
// guilty until proven innocent
|
|
HRESULT hr = WBEM_E_ACCESS_DENIED;
|
|
|
|
// check to see if sid is either Local System or an admin of some sort...
|
|
if ((EqualSid(pSidSystem, m_pObject->m_pSidCreator)) ||
|
|
(S_OK == IsUserAdministrator(m_pObject->m_pSidCreator)))
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// We're done with this
|
|
FreeSid(pSidSystem);
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
}
|
|
else
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
if (WMIScriptClassFactory::LimitReached())
|
|
return RPC_E_DISCONNECTED;
|
|
|
|
HRESULT hrOutter = WBEM_S_NO_ERROR;
|
|
|
|
for(int i = 0; i < lNumObjects; i++)
|
|
{
|
|
HRESULT hrInner;
|
|
|
|
if (m_pObject->m_wsScript.Length())
|
|
hrInner = m_pObject->RunScriptText(apObjects[i]);
|
|
else if (m_pObject->m_wsScriptFileName.Length())
|
|
hrInner = m_pObject->RunScriptFile(apObjects[i]);
|
|
else
|
|
{
|
|
m_pObject->m_pErrorObj->ReportError(L"IndicateToConsumer", L"ScriptText, ScriptFilename", NULL, WBEM_E_ILLEGAL_NULL, true);
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (FAILED(hrInner))
|
|
{
|
|
|
|
m_pObject->m_pErrorObj->ReportError(L"IndicateToConsumer", m_pObject->m_wsErrorLine, m_pObject->m_wsErrorMessage, hrInner, true);
|
|
hrOutter = hrInner;
|
|
// m_pObject->RaiseErrorStatus();
|
|
}
|
|
}
|
|
|
|
return hrOutter;
|
|
}
|
|
|
|
void* CScriptSink::GetInterface(REFIID riid)
|
|
{
|
|
if(riid == IID_IWbemUnboundObjectSink)
|
|
return &m_XSink;
|
|
else return NULL;
|
|
}
|
|
|