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.
792 lines
23 KiB
792 lines
23 KiB
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#include <wbemutil.h>
|
|
#include <GroupsForUser.h>
|
|
#include "ProcKiller.h"
|
|
#include <GenUtils.h>
|
|
#include <ArrTempl.h>
|
|
#include <sddl.h>
|
|
#include <ErrorObj.h>
|
|
#include "cmdline.h"
|
|
#include <Wtsapi32.h>
|
|
#include <winntsec.h>
|
|
#include <lm.h>
|
|
|
|
|
|
#include <malloc.h>
|
|
|
|
#define CMDLINE_PROPNAME_EXECUTABLE L"ExecutablePath"
|
|
#define CMDLINE_PROPNAME_COMMANDLINE L"CommandLineTemplate"
|
|
#define CMDLINE_PROPNAME_USEDEFAULTERRORMODE L"UseDefaultErrorMode"
|
|
#define CMDLINE_PROPNAME_CREATENEWCONSOLE L"CreateNewConsole"
|
|
#define CMDLINE_PROPNAME_CREATENEWPROCESSGROUP L"CreateNewProcessGroup"
|
|
#define CMDLINE_PROPNAME_CREATESEPARATEWOWVDM L"CreateSeparateWowVdm"
|
|
#define CMDLINE_PROPNAME_CREATESHAREDWOWVDM L"CreateSharedWowVdm"
|
|
#define CMDLINE_PROPNAME_PRIORITY L"Priority"
|
|
#define CMDLINE_PROPNAME_WORKINGDIRECTORY L"WorkingDirectory"
|
|
#define CMDLINE_PROPNAME_DESKTOP L"DesktopName"
|
|
#define CMDLINE_PROPNAME_TITLE L"WindowTitle"
|
|
#define CMDLINE_PROPNAME_X L"XCoordinate"
|
|
#define CMDLINE_PROPNAME_Y L"YCoordinate"
|
|
#define CMDLINE_PROPNAME_XSIZE L"XSize"
|
|
#define CMDLINE_PROPNAME_YSIZE L"YSize"
|
|
#define CMDLINE_PROPNAME_XCOUNTCHARS L"XNumCharacters"
|
|
#define CMDLINE_PROPNAME_YCOUNTCHARS L"YNumCharacters"
|
|
#define CMDLINE_PROPNAME_FILLATTRIBUTE L"FillAttribute"
|
|
#define CMDLINE_PROPNAME_SHOWWINDOW L"ShowWindowCommand"
|
|
#define CMDLINE_PROPNAME_FORCEON L"ForceOnFeedback"
|
|
#define CMDLINE_PROPNAME_FORCEOFF L"ForceOffFeedback"
|
|
#define CMDLINE_PROPNAME_INTERACTIVE L"RunInteractively"
|
|
#define CMDLINE_PROPNAME_KILLTIMEOUT L"KillTimeout"
|
|
#define CMDLINE_PROPNAME_CREATORSID L"CreatorSid"
|
|
|
|
HRESULT STDMETHODCALLTYPE CCommandLineConsumer::XProvider::FindConsumer(
|
|
IWbemClassObject* pLogicalConsumer,
|
|
IWbemUnboundObjectSink** ppConsumer)
|
|
{
|
|
CCommandLineSink* pSink = new CCommandLineSink(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* CCommandLineConsumer::GetInterface(REFIID riid)
|
|
{
|
|
if(riid == IID_IWbemEventConsumerProvider)
|
|
return &m_XProvider;
|
|
else return NULL;
|
|
}
|
|
|
|
HRESULT CCommandLineSink::Initialize(IWbemClassObject* pLogicalConsumer)
|
|
{
|
|
// 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;
|
|
|
|
// Get the information
|
|
// ===================
|
|
|
|
HRESULT hres;
|
|
VARIANT v;
|
|
VariantInit(&v);
|
|
|
|
// only one of the pair Executable & commandLine may be null
|
|
// this var counts...
|
|
int nNulls = 0;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_EXECUTABLE, 0, &v,
|
|
NULL, NULL);
|
|
if(FAILED(hres) || V_VT(&v) != VT_BSTR)
|
|
{
|
|
m_wsExecutable = L"";
|
|
nNulls++;
|
|
}
|
|
else
|
|
m_wsExecutable = V_BSTR(&v);
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_COMMANDLINE, 0, &v,
|
|
NULL, NULL);
|
|
if(FAILED(hres) || V_VT(&v) != VT_BSTR)
|
|
{
|
|
m_CommandLine.SetTemplate(L"");
|
|
nNulls++;
|
|
}
|
|
else
|
|
m_CommandLine.SetTemplate(V_BSTR(&v));
|
|
VariantClear(&v);
|
|
|
|
if (nNulls > 1)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_WORKINGDIRECTORY, 0, &v,
|
|
NULL, NULL);
|
|
if(SUCCEEDED(hres) && V_VT(&v) == VT_BSTR)
|
|
m_wsWorkingDirectory = V_BSTR(&v);
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_DESKTOP, 0, &v,
|
|
NULL, NULL);
|
|
if(SUCCEEDED(hres) && V_VT(&v) == VT_BSTR)
|
|
m_wsDesktop = V_BSTR(&v);
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_TITLE, 0, &v,
|
|
NULL, NULL);
|
|
if(FAILED(hres) || V_VT(&v) != VT_BSTR)
|
|
m_title.SetTemplate(L"");
|
|
else
|
|
m_title.SetTemplate(V_BSTR(&v));
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_INTERACTIVE, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_bInteractive = TRUE;
|
|
else
|
|
m_bInteractive = FALSE;
|
|
|
|
m_dwCreationFlags = 0;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_USEDEFAULTERRORMODE, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwCreationFlags |= CREATE_DEFAULT_ERROR_MODE;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATENEWCONSOLE, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwCreationFlags |= CREATE_NEW_CONSOLE;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATENEWPROCESSGROUP, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwCreationFlags |= CREATE_NEW_PROCESS_GROUP;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATESEPARATEWOWVDM, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATESHAREDWOWVDM, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwCreationFlags |= CREATE_SHARED_WOW_VDM;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_PRIORITY, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
if(V_I4(&v) == HIGH_PRIORITY_CLASS ||
|
|
V_I4(&v) == IDLE_PRIORITY_CLASS ||
|
|
V_I4(&v) == NORMAL_PRIORITY_CLASS ||
|
|
V_I4(&v) == REALTIME_PRIORITY_CLASS)
|
|
{
|
|
m_dwCreationFlags |= V_I4(&v);
|
|
}
|
|
else
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
m_dwStartFlags = 0;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_X, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwX = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USEPOSITION;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_Y, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwY = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USEPOSITION;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_XSIZE, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwXSize = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USESIZE;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_YSIZE, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwYSize = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USESIZE;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_XCOUNTCHARS, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwXNumCharacters = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USECOUNTCHARS;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_YCOUNTCHARS, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwYNumCharacters = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USECOUNTCHARS;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_FILLATTRIBUTE, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwFillAttribute = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USEFILLATTRIBUTE;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_SHOWWINDOW, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
{
|
|
m_dwShowWindow = V_I4(&v);
|
|
m_dwStartFlags |= STARTF_USESHOWWINDOW;
|
|
}
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_FORCEON, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwStartFlags |= STARTF_FORCEONFEEDBACK;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_FORCEOFF, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_BOOL && V_BOOL(&v) != VARIANT_FALSE)
|
|
m_dwStartFlags |= STARTF_FORCEOFFFEEDBACK;
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_KILLTIMEOUT, 0, &v,
|
|
NULL, NULL);
|
|
if(V_VT(&v) == VT_I4)
|
|
m_dwKillTimeout = V_I4(&v);
|
|
else
|
|
m_dwKillTimeout = 0;
|
|
|
|
VariantClear(&v);
|
|
|
|
hres = pLogicalConsumer->Get(CMDLINE_PROPNAME_CREATORSID, 0, &v,
|
|
NULL, NULL);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
HRESULT hDebug;
|
|
|
|
long ubound;
|
|
hDebug = SafeArrayGetUBound(V_ARRAY(&v), 1, &ubound);
|
|
|
|
if(SUCCEEDED(hDebug))
|
|
{
|
|
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
|
|
hres = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
SafeArrayUnaccessData(V_ARRAY(&v));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Command Line Consumer could not retrieve creator sid (0x%08X)\n",hres));
|
|
return hres;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
BOOL IsInteractive(HWINSTA hWinsta)
|
|
{
|
|
USEROBJECTFLAGS uof;
|
|
DWORD dwLen;
|
|
BOOL bRes = GetUserObjectInformation(hWinsta, UOI_FLAGS,
|
|
(void*)&uof, sizeof(uof), &dwLen);
|
|
if(!bRes)
|
|
return FALSE;
|
|
return ((uof.dwFlags & WSF_VISIBLE) != 0);
|
|
}
|
|
BOOL WinstaEnumProc(LPTSTR szWindowStation, LPARAM lParam)
|
|
{
|
|
WString* pws = (WString*)lParam;
|
|
|
|
HWINSTA hWinsta = OpenWindowStation(szWindowStation, FALSE,
|
|
WINSTA_ENUMERATE | WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES);
|
|
if(hWinsta == NULL)
|
|
return TRUE;
|
|
|
|
if(IsInteractive(hWinsta))
|
|
{
|
|
*pws = szWindowStation;
|
|
}
|
|
CloseWindowStation(hWinsta);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL GetInteractiveWinstation(WString& wsName)
|
|
{
|
|
wsName.Empty();
|
|
|
|
BOOL bRes = EnumWindowStations(WinstaEnumProc,
|
|
(LPARAM)&wsName);
|
|
return bRes;
|
|
}
|
|
|
|
|
|
HRESULT CCommandLineSink::FindInteractiveInfo()
|
|
{
|
|
BOOL bRes = GetInteractiveWinstation(m_wsWindowStation);
|
|
if(!bRes)
|
|
{
|
|
return WBEM_E_FAILED;
|
|
}
|
|
if(m_wsWindowStation.Length() == 0)
|
|
return WBEM_E_NOT_FOUND;
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
HRESULT GetSidUse(PSID pSid, SID_NAME_USE& use)
|
|
{
|
|
DWORD dwNameLen = 0;
|
|
DWORD dwDomainLen = 0;
|
|
LPWSTR pUser = 0;
|
|
LPWSTR pDomain = 0;
|
|
use = SidTypeInvalid;
|
|
|
|
// Do the first lookup to get the buffer sizes required.
|
|
// =====================================================
|
|
|
|
BOOL bRes = LookupAccountSidW(
|
|
NULL,
|
|
pSid,
|
|
pUser,
|
|
&dwNameLen,
|
|
pDomain,
|
|
&dwDomainLen,
|
|
&use
|
|
);
|
|
|
|
DWORD dwLastErr = GetLastError();
|
|
|
|
if (dwLastErr != ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
// Allocate the required buffers and look them up again.
|
|
// =====================================================
|
|
|
|
pUser = new wchar_t[dwNameLen + 1];
|
|
if (!pUser)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pDomain = new wchar_t[dwDomainLen + 1];
|
|
if (!pDomain)
|
|
{
|
|
delete pUser;
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
bRes = LookupAccountSidW(
|
|
NULL,
|
|
pSid,
|
|
pUser,
|
|
&dwNameLen,
|
|
pDomain,
|
|
&dwDomainLen,
|
|
&use
|
|
);
|
|
|
|
delete [] pUser;
|
|
delete [] pDomain;
|
|
|
|
if (bRes)
|
|
return WBEM_S_NO_ERROR;
|
|
else
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
|
|
bool GetLoggedOnUserViaTS(
|
|
CNtSid& sidLoggedOnUser)
|
|
{
|
|
bool fRet = false;
|
|
bool fCont = true;
|
|
PWTS_SESSION_INFO psesinfo = NULL;
|
|
DWORD dwSessions = 0;
|
|
LPWSTR wstrUserName = NULL;
|
|
LPWSTR wstrDomainName = NULL;
|
|
LPWSTR wstrWinstaName = NULL;
|
|
DWORD dwSize = 0L;
|
|
|
|
try
|
|
{
|
|
if(!(::WTSEnumerateSessions(
|
|
WTS_CURRENT_SERVER_HANDLE,
|
|
0,
|
|
1,
|
|
&psesinfo,
|
|
&dwSessions) && psesinfo))
|
|
{
|
|
fCont = false;
|
|
}
|
|
|
|
if(fCont)
|
|
{
|
|
for(int j = 0; j < dwSessions && !fRet; j++, fCont = true)
|
|
{
|
|
if(psesinfo[j].State != WTSActive)
|
|
{
|
|
fCont = false;
|
|
}
|
|
|
|
if(fCont)
|
|
{
|
|
if(!(::WTSQuerySessionInformation(
|
|
WTS_CURRENT_SERVER_HANDLE,
|
|
psesinfo[j].SessionId,
|
|
WTSUserName,
|
|
&wstrUserName,
|
|
&dwSize) && wstrUserName))
|
|
{
|
|
fCont = false;
|
|
}
|
|
}
|
|
|
|
if(fCont)
|
|
{
|
|
if(!(::WTSQuerySessionInformation(
|
|
WTS_CURRENT_SERVER_HANDLE,
|
|
psesinfo[j].SessionId,
|
|
WTSDomainName,
|
|
&wstrDomainName,
|
|
&dwSize) && wstrDomainName))
|
|
{
|
|
fCont = false;
|
|
}
|
|
}
|
|
|
|
if(fCont)
|
|
{
|
|
if(!(::WTSQuerySessionInformation(
|
|
WTS_CURRENT_SERVER_HANDLE,
|
|
psesinfo[j].SessionId,
|
|
WTSWinStationName,
|
|
&wstrWinstaName,
|
|
&dwSize) && wstrWinstaName))
|
|
{
|
|
fCont = false;
|
|
}
|
|
}
|
|
|
|
if(fCont)
|
|
{
|
|
if(wbem_wcsicmp(wstrWinstaName, L"Console") != 0)
|
|
{
|
|
fCont = false;
|
|
}
|
|
}
|
|
|
|
if(fCont)
|
|
{
|
|
WCHAR buf[256];
|
|
DWORD bufSize = 255;
|
|
|
|
if (GetComputerNameW(buf, &bufSize))
|
|
{
|
|
DWORD nRet = 0;
|
|
|
|
// if it's a local account, we look it up locally
|
|
// else we find a DC to look up.
|
|
WCHAR* pServer = NULL;
|
|
if (0 == wbem_wcsicmp(buf, wstrDomainName))
|
|
pServer = NULL;
|
|
else
|
|
nRet = NetGetDCName(NULL, wstrDomainName, (LPBYTE *)&pServer);
|
|
|
|
if (nRet == 0)
|
|
{
|
|
// That establishes that this user
|
|
// is associated with the interactive
|
|
// desktop.
|
|
CNtSid sidInteractive(wstrUserName, pServer);
|
|
|
|
if(sidInteractive.GetStatus() == CNtSid::NoError)
|
|
{
|
|
sidLoggedOnUser = sidInteractive;
|
|
fRet = true;
|
|
}
|
|
|
|
if (pServer)
|
|
NetApiBufferFree(pServer);
|
|
}
|
|
else
|
|
fRet = false;
|
|
}
|
|
}
|
|
|
|
if(wstrUserName)
|
|
{
|
|
WTSFreeMemory(wstrUserName);
|
|
wstrUserName = NULL;
|
|
}
|
|
if(wstrDomainName)
|
|
{
|
|
WTSFreeMemory(wstrDomainName);
|
|
wstrDomainName = NULL;
|
|
}
|
|
if(wstrWinstaName)
|
|
{
|
|
WTSFreeMemory(wstrWinstaName);
|
|
wstrWinstaName = NULL;
|
|
}
|
|
}
|
|
if (psesinfo)
|
|
WTSFreeMemory(psesinfo);
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
if(wstrUserName)
|
|
{
|
|
WTSFreeMemory(wstrUserName);
|
|
wstrUserName = NULL;
|
|
}
|
|
if(wstrDomainName)
|
|
{
|
|
WTSFreeMemory(wstrDomainName);
|
|
wstrDomainName = NULL;
|
|
}
|
|
if(wstrWinstaName)
|
|
{
|
|
WTSFreeMemory(wstrWinstaName);
|
|
wstrWinstaName = NULL;
|
|
}
|
|
|
|
if (psesinfo)
|
|
WTSFreeMemory(psesinfo);
|
|
|
|
fRet = false;
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CCommandLineSink::XSink::CreateProcessNT(WCHAR* pCommandLine, WCHAR* pTitle, PROCESS_INFORMATION& pi, FILETIME& now)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
WCHAR* pDesktop = NULL;
|
|
|
|
WString wsDesktop;
|
|
|
|
if(m_pObject->m_bInteractive)
|
|
{
|
|
if(FAILED(m_pObject->FindInteractiveInfo()))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "No interactive window station found!\n"));
|
|
return WBEM_E_FAILED;
|
|
}
|
|
wsDesktop = m_pObject->m_wsWindowStation;
|
|
wsDesktop += L"\\Default";
|
|
pDesktop = (wchar_t*)wsDesktop;
|
|
|
|
CNtSid user;
|
|
|
|
if (!GetLoggedOnUserViaTS(user))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Could not determine logged on user\n"));
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
|
|
SID_NAME_USE use;
|
|
if (FAILED(hr =GetSidUse(m_pObject->m_pSidCreator, use)))
|
|
return hr;
|
|
|
|
if (use == SidTypeUser)
|
|
{
|
|
if (!EqualSid(m_pObject->m_pSidCreator, user.GetPtr()))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Command line event consumer will only run interactively\non a workstation that the creator is logged into.\n"));
|
|
m_pObject->m_pErrorObj->ReportError(L"AccessCheck", L"RunInteractively",
|
|
NULL, WBEM_E_ACCESS_DENIED, true);
|
|
|
|
return WBEM_E_ACCESS_DENIED;
|
|
}
|
|
// else we're fine continue.
|
|
DEBUGTRACE((LOG_ESS, "User and creator are one in the same\n"));
|
|
}
|
|
else
|
|
{
|
|
if (0 != IsUserInGroup(user.GetPtr(), m_pObject->m_pSidCreator))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Command line event consumer will only run interactively\non a workstation that the creator is logged into.\n"));
|
|
m_pObject->m_pErrorObj->ReportError(L"AccessCheck", L"RunInteractively",
|
|
NULL, WBEM_E_ACCESS_DENIED, true);
|
|
|
|
return WBEM_E_ACCESS_DENIED;
|
|
}
|
|
else
|
|
{
|
|
DEBUGTRACE((LOG_ESS, "User is in the group!\n"));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
WCHAR* szApplicationName = (m_pObject->m_wsExecutable.Length() == 0) ? NULL : ((wchar_t*)m_pObject->m_wsExecutable);
|
|
WCHAR* szWorkingDirectory = (m_pObject->m_wsWorkingDirectory.Length() == 0) ? NULL : ((wchar_t*)m_pObject->m_wsWorkingDirectory);
|
|
|
|
struct _STARTUPINFOW si;
|
|
si.cb = sizeof(si);
|
|
si.lpReserved = NULL;
|
|
si.cbReserved2 = 0;
|
|
si.lpReserved2 = NULL;
|
|
si.lpDesktop = pDesktop;
|
|
si.lpTitle = pTitle;
|
|
si.dwX = m_pObject->m_dwX;
|
|
si.dwY = m_pObject->m_dwY;
|
|
si.dwXSize = m_pObject->m_dwXSize;
|
|
si.dwYSize = m_pObject->m_dwYSize;
|
|
si.dwXCountChars = m_pObject->m_dwXNumCharacters;
|
|
si.dwYCountChars = m_pObject->m_dwYNumCharacters;
|
|
si.dwFillAttribute = m_pObject->m_dwFillAttribute;
|
|
si.dwFlags = m_pObject->m_dwStartFlags;
|
|
si.wShowWindow = (WORD)m_pObject->m_dwShowWindow;
|
|
|
|
#ifdef HHANCE_DEBUG_CODE
|
|
DEBUGTRACE((LOG_ESS, "Calling Create process\n"));
|
|
#endif
|
|
|
|
BOOL bRes = CreateProcessW(szApplicationName, pCommandLine,
|
|
NULL, NULL, FALSE, m_pObject->m_dwCreationFlags,
|
|
NULL, szWorkingDirectory, &si, &pi);
|
|
|
|
if (!bRes)
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
m_pObject->m_pErrorObj->ReportError(L"CreateProcess", szApplicationName ? szApplicationName : pCommandLine, NULL, dwErr, true);
|
|
ERRORTRACE((LOG_ESS, "CreateProcess failed, 0x%08X\n", dwErr));
|
|
}
|
|
#ifdef HHANCE_DEBUG_CODE
|
|
else
|
|
DEBUGTRACE((LOG_ESS, "Create Process succeeded\n"));
|
|
#endif
|
|
|
|
|
|
// get current time for shutdown info
|
|
GetSystemTimeAsFileTime(&now);
|
|
|
|
if (!bRes)
|
|
hr = WBEM_E_FAILED;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CCommandLineSink::XSink::IndicateToConsumer(
|
|
IWbemClassObject* pLogicalConsumer, long lNumObjects,
|
|
IWbemClassObject** apObjects)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
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
|
|
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))
|
|
{
|
|
if (hr == WBEM_E_ACCESS_DENIED)
|
|
ERRORTRACE((LOG_ESS, "Command line event consumer may only be used by an administrator\n"));
|
|
return hr;
|
|
}
|
|
}
|
|
else
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
|
|
for(int i = 0; i < lNumObjects; i++)
|
|
{
|
|
BSTR strCommandLine = m_pObject->m_CommandLine.Apply(apObjects[i]);
|
|
if(strCommandLine == NULL)
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Invalid command line!\n"));
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
WString wsCommandLine = strCommandLine;
|
|
SysFreeString(strCommandLine);
|
|
|
|
BSTR bstrTitle = m_pObject->m_title.Apply(apObjects[i]);
|
|
WString wsTitle = bstrTitle;
|
|
if (bstrTitle)
|
|
SysFreeString(bstrTitle);
|
|
|
|
FILETIME now;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
WCHAR* pCommandLine = ((wsCommandLine.Length() == 0) ? NULL : (wchar_t *)wsCommandLine);;
|
|
WCHAR* pTitle = ((wsTitle.Length() == 0) ? NULL : (wchar_t *)wsTitle);
|
|
|
|
hr = CreateProcessNT(pCommandLine, pTitle, pi, now);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Failed to CreateProcess %S. Error 0x%X\n", (LPCWSTR)wsCommandLine, hr));
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
if (m_pObject->m_dwKillTimeout)
|
|
{
|
|
|
|
WAYCOOL_FILETIME then(now);
|
|
then.AddSeconds(m_pObject->m_dwKillTimeout);
|
|
|
|
hr = g_procKillerTimer.ScheduleAssassination(pi.hProcess, (FILETIME)then);
|
|
|
|
if (FAILED(hr))
|
|
DEBUGTRACE((LOG_ESS, "Could not schedule process termination\n"));
|
|
}
|
|
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
void* CCommandLineSink::GetInterface(REFIID riid)
|
|
{
|
|
if(riid == IID_IWbemUnboundObjectSink)
|
|
return &m_XSink;
|
|
else return NULL;
|
|
}
|
|
|