sa.nLength = sa.size();
sa.lpSecurityDescriptor = null;
sa.bInheritHandle = true;// 1; // true otherwise streams are
// not piped
}
inRead = new PointerByReference();
inWrite = new PointerByReference();
outRead = new PointerByReference();
outWrite = new PointerByReference();
errRead = new PointerByReference();
errWrite = new PointerByReference();
if (MyKernel32.INSTANCE.CreatePipe(inRead, inWrite, sa, 0) == 0 || MyKernel32.INSTANCE.CreatePipe(outRead, outWrite, sa, 0) == 0
|| MyKernel32.INSTANCE.CreatePipe(errRead, errWrite, sa, 0) == 0)
{
log("Error in CreatePipe " + Integer.toHexString(MyKernel32.INSTANCE.GetLastError()));
return false;
}
_startupInfo.dwFlags = MyKernel32.STARTF_USESTDHANDLES;
_startupInfo.hStdInput = inRead.getValue();
_startupInfo.hStdOutput = outWrite.getValue();
_startupInfo.hStdError = errWrite.getValue();
if (!MyKernel32.INSTANCE.SetHandleInformation(inWrite.getValue(), MyKernel32.HANDLE_FLAG_INHERIT, 0)
|| !MyKernel32.INSTANCE.SetHandleInformation(outRead.getValue(), MyKernel32.HANDLE_FLAG_INHERIT, 0)
|| !MyKernel32.INSTANCE.SetHandleInformation(errRead.getValue(), MyKernel32.HANDLE_FLAG_INHERIT, 0)
// for some unknown reason: if we add the following
// lines we do not get "operation on non socket" error
// in mina
|| !MyKernel32.INSTANCE.SetHandleInformation(inWrite.getValue(), MyKernel32.HANDLE_FLAG_PROTECT_FROM_CLOSE,
MyKernel32.HANDLE_FLAG_PROTECT_FROM_CLOSE)
|| !MyKernel32.INSTANCE.SetHandleInformation(outRead.getValue(), MyKernel32.HANDLE_FLAG_PROTECT_FROM_CLOSE,
MyKernel32.HANDLE_FLAG_PROTECT_FROM_CLOSE)
|| !MyKernel32.INSTANCE.SetHandleInformation(errRead.getValue(), MyKernel32.HANDLE_FLAG_PROTECT_FROM_CLOSE,
MyKernel32.HANDLE_FLAG_PROTECT_FROM_CLOSE))
{
log("error in set handle -> abort start");
return false;
}
if (this._redirectErrorStream)
MyKernel32.INSTANCE.SetHandleInformation(errRead.getValue(), MyKernel32.HANDLE_FLAG_INHERIT, 0);
}
int creationFlag = 0;
if (!_visible)
{
creationFlag |= MyKernel32.CREATE_NO_WINDOW | MyKernel32.CREATE_UNICODE_ENVIRONMENT;
_startupInfo.lpTitle = null;
}
else
{
creationFlag |= MyKernel32.CREATE_NEW_CONSOLE | MyKernel32.CREATE_UNICODE_ENVIRONMENT;
_startupInfo.lpTitle = new WString(_title);
if (_minimized)
{
_startupInfo.wShowWindow |= MyKernel32.SW_SHOWMINIMIZED | MyKernel32.SW_SHOWNOACTIVATE;
_startupInfo.dwFlags |= MyKernel32.STARTF_USESHOWWINDOW;
}
}
creationFlag |= getPriorityFlag();
// do not inherit handles. otherwise resources are not freed if
// parent is killed
// inherit only when we need to pipe the streams
_startupInfo.write();
WString cmd = new WString(_cmd);
WString wDir = getWorkingDir() == null ? null : new WString(getWorkingDir());
String stdUser = standardizeUser(_user);
StringBlock environment = null;
WString[] env = null;
if (_environment.size() != 0)
{
env = new WString[_environment.size()];
int i = 0;
for (String[] entry : _environment)
{
env[i++] = new WString(entry[0] + "=" + entry[1]);
}
environment = new StringBlock(env);
}
if (_desktop != null)
{
_startupInfo.lpDesktop = new WString(_desktop);
log("setting desktop "+_desktop);
}
if (_logonActiveSession)
{
log("start process in active session");
int session = 0xFFFFFFFF;
// wait until we have an active session
while (session == 0xFFFFFFFF)
{
session = MyKernel32.INSTANCE.WTSGetActiveConsoleSessionId();
if (session == 0xFFFFFFFF)
Thread.sleep(1000);
log("active session: "+session);
}
PointerByReference phToken = new PointerByReference();
// wait for a user to log on to the session
boolean userLoggedOn = false;
int retries = 0;
while (!userLoggedOn)
{
result = MyWtsapi32.INSTANCE.WTSQueryUserToken(session, phToken);
userLoggedOn = result || MyKernel32.INSTANCE.GetLastError() != 1008;
if (!userLoggedOn)
{
Thread.sleep(1000);
retries++;
}
}
// if user just logged on: wait for the desktop to get up.
// TODO evntl. add a configuration property for the time to wait.
if (retries > 0)
Thread.sleep(10000);
if (!doesUserHavePrivilege(MyAdvapi.SE_TCB_NAME))
log("WARNING: Process does not have the SE_TCB_NAME privilege !!");
// start the application
if (result)
{
log("got session token: "+phToken.getValue());
PointerByReference phNewToken = new PointerByReference();
result = MyAdvapi.INSTANCE.DuplicateTokenEx(phToken.getValue(), 0x2000000, null, 0, 1, phNewToken);
if (result)
{
log("duplicated token: "+phNewToken.getValue());
//_startupInfo.lpDesktop = new WString("winsta0\\default");
creationFlag = 0;
creationFlag |= MyKernel32.CREATE_NO_WINDOW | MyKernel32.CREATE_UNICODE_ENVIRONMENT;
creationFlag |= getPriorityFlag();
result = MyAdvapi.INSTANCE.CreateProcessAsUserW(phNewToken.getValue(), null, cmd, null, null, _pipeStreams, creationFlag,
null, new WString(getWorkingDir()), _startupInfo, _processInformation);
log("started "+result);
}
}
}
else
if (stdUser == null || stdUser.equals(currentUser()))
{
result = MyKernel32.INSTANCE.CreateProcessW(null, cmd, null, null, _pipeStreams, creationFlag, environment, wDir, _startupInfo,
_processInformation);
}
else
{
WString user = null;
;
WString domain = null;
;
int i = _user.lastIndexOf("\\");
if (i > 0)
{
user = new WString(_user.substring(_user.lastIndexOf("\\") + 1));
domain = new WString(_user.substring(0, _user.lastIndexOf("\\")));
}
else
user = new WString(_user);
WString password = null;
if (_password != null)
password = new WString(_password);
log("current user :: requested user: " + currentUserName() + " :: " + stdUser);
// in windows 2008: system user seems to be <computername>$
// could not find documentation on this.
if (!("SYSTEM".equals(currentUserName()) || currentUserName().endsWith("$")))
{
// createProcessWithLogon : cmd line is only 1024 char long
// parent process is not current process.
// -> use CreateProcessAsUser
// result = MyAdvapi.INSTANCE.CreateProcessWithLogonW(user,
// domain, password, MyAdvapi.LOGON_WITH_PROFILE, null, cmd,
// creationFlag, null, wDir, _startupInfo,
// _processInformation);
/**/
PointerByReference phToken = new PointerByReference();
String stUser = user.toString();
String stDomain = domain == null ? null : domain.toString();
String stPassword = password == null ? "" : password.toString();
result = true;
// result = MyAdvapi.INSTANCE.LogonUserA(stUser, stDomain,
// stPassword, MyAdvapi.LOGON32_LOGON_NEW_CREDENTIALS,
// MyAdvapi.LOGON32_PROVIDER_WINNT50, phToken);
if (result)
{
// HANDLE hCurrentProcess =
// MyKernel32.INSTANCE.GetCurrentProcess();
// PointerByReference hTokenSelf = new
// PointerByReference();
// result =
// MyAdvapi.INSTANCE.OpenProcessToken(hCurrentProcess,
// MyAdvapi.TOKEN_READ | MyAdvapi.TOKEN_WRITE |
// MyAdvapi.TOKEN_DUPLICATE |
// MyAdvapi.TOKEN_IMPERSONATE, hTokenSelf );
/*
* Memory pSD = new
* Memory(MyAdvapi.SECURITY_DESCRIPTOR_MIN_LENGTH);
* pSD.clear(); if (result) result =
* MyAdvapi.INSTANCE.InitializeSecurityDescriptor(pSD,
* MyAdvapi.SECURITY_DESCRIPTOR_REVISION);
*
* if (result) result =
* MyAdvapi.INSTANCE.SetSecurityDescriptorDacl(pSD,
* true, null, false);
*/
if (result)
{
/*
* SECURITY_ATTRIBUTES sap = new
* SECURITY_ATTRIBUTES(); sap.clear(); sap.nLength =
* sap.size(); sap.lpSecurityDescriptor = pSD;
* sap.bInheritHandle = false;
*/
// result =
// MyAdvapi.INSTANCE.ImpersonateLoggedOnUser(phToken.getValue());
/**/// System.out.println(MyAdvapi.SE_ASSIGNPRIMARYTOKEN_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_ASSIGNPRIMARYTOKEN_NAME));
// System.out.println(MyAdvapi.SE_INCREASE_QUOTA_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_INCREASE_QUOTA_NAME));
// System.out.println(MyAdvapi.SE_DEBUG_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_DEBUG_NAME));
// System.out.println(MyAdvapi.SE_TCB_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_TCB_NAME));
// */
/**/if (result)
{
// result =
// setPrivilege(hTokenSelf.getValue(),
// MyAdvapi.SE_ASSIGNPRIMARYTOKEN_NAME, true)
// && setPrivilege(hTokenSelf.getValue(),
// MyAdvapi.SE_INCREASE_QUOTA_NAME, true)
// && setPrivilege(hTokenSelf.getValue(),
// MyAdvapi.SE_DEBUG_NAME, true)
// && setPrivilege(hTokenSelf.getValue(),
// MyAdvapi.SE_TCB_NAME, true)
;
}
// System.out.println(MyAdvapi.SE_ASSIGNPRIMARYTOKEN_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_ASSIGNPRIMARYTOKEN_NAME));
// System.out.println(MyAdvapi.SE_INCREASE_QUOTA_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_INCREASE_QUOTA_NAME));
// System.out.println(MyAdvapi.SE_DEBUG_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_DEBUG_NAME));
// System.out.println(MyAdvapi.SE_TCB_NAME+" "+this.doesUserHavePrivilege(MyAdvapi.SE_TCB_NAME));
// */
// MyKernel32.INSTANCE.CloseHandle(hTokenSelf.getValue());
if (!doesUserHavePrivilege(MyAdvapi.SE_ASSIGNPRIMARYTOKEN_NAME))
log("Process does not have the SE_ASSIGNPRIMARYTOKEN_NAME privilege !!");
if (!doesUserHavePrivilege(MyAdvapi.SE_INCREASE_QUOTA_NAME))
log("Process does not have the SE_INCREASE_QUOTA_NAME privilege !!");
result = MyAdvapi.INSTANCE.LogonUserA(stUser, stDomain, stPassword, MyAdvapi.LOGON32_LOGON_INTERACTIVE,
MyAdvapi.LOGON32_PROVIDER_DEFAULT, phToken);
if (result)
// result =
// MyAdvapi.INSTANCE.CreateProcessWithLogonW(user,
// domain, password,
// MyAdvapi.LOGON_NETCREDENTIALS_ONLY, null,
// cmd, creationFlag, null, wDir, _startupInfo,
// _processInformation);
result = MyAdvapi.INSTANCE.CreateProcessAsUserW(phToken.getValue(), null, cmd, null, // sap,
null, true,// _pipeStreams,
creationFlag, null, null,// getWorkingDir(),
_startupInfo, _processInformation);
}
}
/**/
}
else
{
/*
* _startupInfo = new STARTUPINFO(); _startupInfo.clear();
* _processInformation = new PROCESS_INFORMATION();
* _processInformation.clear();
*/
PointerByReference phToken = new PointerByReference();
String stUser = user.toString();
String stDomain = domain == null ? null : domain.toString();
String stPassword = password == null ? "" : password.toString();
result = MyAdvapi.INSTANCE.LogonUserW(user, domain, password, MyAdvapi.LOGON32_LOGON_INTERACTIVE,
MyAdvapi.LOGON32_PROVIDER_DEFAULT, phToken);
log("logonUserA " + result);
if (result)
{
// result =
// MyAdvapi.INSTANCE.ImpersonateLoggedOnUser(phToken.getValue());
if (result)
// result =
// MyAdvapi.INSTANCE.CreateProcessWithLogonW(user,
// domain, password,
// MyAdvapi.LOGON_NETCREDENTIALS_ONLY, null, cmd,
// creationFlag, null, wDir, _startupInfo,
// _processInformation);
result = MyAdvapi.INSTANCE.CreateProcessAsUserW(phToken.getValue(), null, cmd, null, null, _pipeStreams, creationFlag,
null, new WString(getWorkingDir()), _startupInfo, _processInformation);
}
}