Leaked source code of windows server 2003
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

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