Exemplo n.º 1
0
static BOOL
StartUserShell(
    IN OUT PWLSESSION Session)
{
    LPVOID lpEnvironment = NULL;
    BOOLEAN Old;
    BOOL ret;

    /* Create environment block for the user */
    if (!CreateEnvironmentBlock(&lpEnvironment, Session->UserToken, TRUE))
    {
        WARN("WL: CreateEnvironmentBlock() failed\n");
        return FALSE;
    }

    /* Get privilege */
    /* FIXME: who should do it? winlogon or gina? */
    /* FIXME: reverting to lower privileges after creating user shell? */
    RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, TRUE, FALSE, &Old);

    ret = Session->Gina.Functions.WlxActivateUserShell(
                Session->Gina.Context,
                L"Default",
                NULL, /* FIXME */
                lpEnvironment);

    DestroyEnvironmentBlock(lpEnvironment);
    return ret;
}
Exemplo n.º 2
0
static BOOL
StartTaskManager(
    IN OUT PWLSESSION Session)
{
    LPVOID lpEnvironment;
    BOOL ret;

    if (!Session->Gina.Functions.WlxStartApplication)
        return FALSE;

    if (!CreateEnvironmentBlock(
        &lpEnvironment,
        Session->UserToken,
        TRUE))
    {
        return FALSE;
    }

    ret = Session->Gina.Functions.WlxStartApplication(
        Session->Gina.Context,
        L"Default",
        lpEnvironment,
        L"taskmgr.exe");

    DestroyEnvironmentBlock(lpEnvironment);
    return ret;
}
Exemplo n.º 3
0
// Replace this process' environment with the current system environment
void UpdateEnvironment()
{
    // Fetch the current environment for the user
    HANDLE accessToken;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &accessToken))
        return;

    wchar_t* environment;
    if (!CreateEnvironmentBlock((LPVOID*)&environment, accessToken, FALSE))
        return;

    // Empty the current environment
    QStringList variables;
    wchar_t* currentEnvironment = GetEnvironmentStrings();
    for (TCHAR* p = currentEnvironment; *p != 0;)
    {
        QString variable = QString::fromUtf16(p);
        QString name = variable.section("=", 0, 0);
        // Ignore entries for drive current directory entries that have no name
        if (name.size() > 0)
            variables.append(name);
        p += wcslen(p) + 1;
    }
    if (currentEnvironment)
        FreeEnvironmentStrings(currentEnvironment);

    // Now we've finished enumerating the current environment, we can safely delete variables
    foreach (QString name, variables)
    {
        SetEnvironmentVariable(name.utf16(), NULL);
    }
Exemplo n.º 4
0
int ActivePet::launch(std::wstring exePath, std::wstring originalDocPath){

	wchar_t commandLine[4096] = { '\0' };
	if (originalDocPath != L"") {

		// Build the command line.
	    std::wstring editableDocPath = edit(originalDocPath);
		wcscat(commandLine, L"\"");
		wcscat(commandLine, exePath.c_str());
		wcscat(commandLine, L"\" \"");
		wcscat(commandLine, editableDocPath.c_str());
		wcscat(commandLine, L"\"");
	}
    auto_close<void*, &::DestroyEnvironmentBlock> environment(NULL);
	if (!CreateEnvironmentBlock(&environment, m_session.get(), FALSE)) {
        printf("CreateEnvironmentBlock() failed: %d", GetLastError());
		return -30;
	}
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi = {};
	if (!CreateProcessAsUser(m_session.get(),
							 exePath.c_str(),
							 commandLine,
							 NULL,
							 NULL,
							 FALSE,
							 CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE,
							 environment.get(),
							 NULL, // lpCurrentDirectory,
							 &si,
							 &pi)) {
        printf("CreateProcessAsUser() failed: %d", GetLastError());
		return -30;
	}
	if (!AssignProcessToJobObject(m_job.get(), pi.hProcess)) {
        printf("AssignProcessToJobObject() failed: %d", GetLastError());
		return -30;
	}
	if (!ResumeThread(pi.hThread)) {
        printf("ResumeThread() failed: %d", GetLastError());
		return -30;
	}
    if (WaitForInputIdle(pi.hProcess, INFINITE) != ERROR_SUCCESS) {
        printf("WaitForInputIdle() failed: %d", GetLastError());
		return -30;
	}
    InjectAndCall(pi.hProcess, "ApplyHooks", 10000);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

    return 0;
}
Exemplo n.º 5
0
int OOBase::Environment::get_user(HANDLE hToken, env_table_t& tabEnv)
{
	LPVOID lpEnv = NULL;
	if (!CreateEnvironmentBlock(&lpEnv,hToken,FALSE))
		return GetLastError();

	int err = process_block(static_cast<wchar_t*>(lpEnv),tabEnv);
		
	if (lpEnv)
		DestroyEnvironmentBlock(lpEnv);

	return err;
}
Exemplo n.º 6
0
BOOL
WINAPI
ExpandEnvironmentStringsForUserW(IN HANDLE hToken,
                                 IN LPCWSTR lpSrc,
                                 OUT LPWSTR lpDest,
                                 IN DWORD dwSize)
{
    BOOL Ret = FALSE;
    PVOID lpEnvironment;

    if (lpSrc == NULL || lpDest == NULL || dwSize == 0)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (CreateEnvironmentBlock(&lpEnvironment,
                               hToken,
                               FALSE))
    {
        UNICODE_STRING SrcU, DestU;
        NTSTATUS Status;

        /* Initialize the strings */
        RtlInitUnicodeString(&SrcU, lpSrc);
        DestU.Length = 0;
        DestU.MaximumLength = dwSize * sizeof(WCHAR);
        DestU.Buffer = lpDest;

        /* Expand the strings */
        Status = RtlExpandEnvironmentStrings_U((PWSTR)lpEnvironment,
                                               &SrcU,
                                               &DestU,
                                               NULL);

        DestroyEnvironmentBlock(lpEnvironment);

        if (NT_SUCCESS(Status))
        {
            Ret = TRUE;
        }
        else
        {
            SetLastError(RtlNtStatusToDosError(Status));
        }
    }

    return Ret;
}
Exemplo n.º 7
0
BOOL ExecMyself( LPCTSTR lpCommandLine )
{
    DWORD dwSession, r;
    HANDLE hToken;
    LPVOID lpEnv;
    STARTUPINFO startupInfo;
    PROCESS_INFORMATION processInformation;
    TCHAR szApplicationName[ 1024 ];
    TCHAR szCommandLine[ 1024 ];

    r = GetModuleFileName( NULL, szApplicationName, _countof( szApplicationName ) );
    if( r == 0 || r >= _countof( szApplicationName ) ){
        DebugMsg( _T("GetModuleFileName:%d"), GetLastError() );
        return FALSE;
    }

    if( StringCchPrintf( szCommandLine, _countof( szCommandLine ), _T("\"%s\" %s"), szApplicationName, lpCommandLine ) != S_OK ) return FALSE;
    dwSession = WTSGetActiveConsoleSessionId();
    if( dwSession == 0xFFFFFFFF ){
        DebugMsg( _T("WTSGetActiveConsoleSessionId:%d"), GetLastError() );
        return FALSE;
    }
    if( !WTSQueryUserToken( dwSession, &hToken ) ){
        DebugMsg( _T("WTSQueryUserToken:%d"), GetLastError() );
        return FALSE;
    }
    if( !CreateEnvironmentBlock( &lpEnv, hToken, FALSE ) ){
        DebugMsg( _T("CreateEnvironmentBlock:%d"), GetLastError() );
        return FALSE;
    }

    ZeroMemory( &startupInfo, sizeof(STARTUPINFO) );
    startupInfo.cb = sizeof(STARTUPINFO);
    startupInfo.lpDesktop = _T( "winsta0\\default" );
    if( !CreateProcessAsUser( hToken, szApplicationName, szCommandLine, NULL, NULL, 
        FALSE, CREATE_UNICODE_ENVIRONMENT, lpEnv, NULL, &startupInfo, &processInformation) )
    {
        DebugMsg( _T("CreateProcessAsUser:%d"), GetLastError() );
        return FALSE;
    }

    CloseHandle(processInformation.hThread);
    CloseHandle(processInformation.hProcess);

    return TRUE;
}
Exemplo n.º 8
0
void wmain(int argc, WCHAR *argv[])
{
    DWORD     dwSize;
    HANDLE    hToken;
    LPVOID    lpvEnv;
    PROCESS_INFORMATION pi = {0};
    STARTUPINFO         si = {0};
    WCHAR               szUserProfile[256] = L"";

    si.cb = sizeof(STARTUPINFO);

    if (argc != 4)
    {
        /*    wprintf(L"Usage: %s [user@domain] [password] [cmd]", argv[0]);
            wprintf(L"\n\n"); */
        //   return;
    }

    dwSize = sizeof(szUserProfile)/sizeof(WCHAR);


    OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken);
    //ShowLastError(L"OpenProcessToken");
    //SetPrivilege(&hToken, SE_SYSTEMTIME_NAME,TRUE);
    // if(!SetPrivilege(hToken, SE_TCB_NAME , TRUE)) printf("Set Privilege Failed");// DisplayError(L"SetPrivilege");
    //if (!LogonUser(argv[1], NULL , argv[2], LOGON32_LOGON_INTERACTIVE,    LOGON32_PROVIDER_DEFAULT, &hToken))       DisplayError(L"LogonUser");

    if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))    ShowLastError(L"CreateEnvironmentBlock");

    dwSize = sizeof(szUserProfile)/sizeof(WCHAR);

    if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize))        ShowLastError(L"GetUserProfileDirectory");
    //
    // TO DO: change NULL to '.' to use local account database
    //
    if (!CreateProcessWithLogonW(argv[1], NULL, argv[2],             LOGON_WITH_PROFILE, NULL, argv[3],             CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfile,             &si, &pi))

        ShowLastError(L"CreateProcessWithLogonW");

    if (!DestroyEnvironmentBlock(lpvEnv))        ShowLastError(L"DestroyEnvironmentBlock");


    CloseHandle(hToken);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}
Exemplo n.º 9
0
runner::env_vars_list_t runner::set_environment_for_process() const
{
    auto curr_vars = read_environment(GetEnvironmentStringsW());

    if (options.environmentMode == "user-default")
    {
        LPVOID envBlock = NULL;

        CreateEnvironmentBlock(&envBlock, NULL, FALSE);

        auto default_vars = read_environment((WCHAR*)envBlock);

        DestroyEnvironmentBlock(envBlock);

        for (auto i = default_vars.cbegin(); i != default_vars.cend(); ++i)
        {
            SetEnvironmentVariableA(i->first.c_str(), i->second.c_str());
        }

        for (auto i = curr_vars.cbegin(); i != curr_vars.cend(); ++i)
        {
            if (std::find(default_vars.cbegin(), default_vars.cend(), *i) == default_vars.cend())
            {
                SetEnvironmentVariableA(i->first.c_str(), NULL);
            }
        }
    }
    else if (options.environmentMode == "clear")
    {
        for (auto i = curr_vars.cbegin(); i != curr_vars.cend(); ++i)
        {
            SetEnvironmentVariableA(i->first.c_str(), NULL);
        }
    }

    for (auto i = options.environmentVars.cbegin(); i != options.environmentVars.cend(); ++i) {
        SetEnvironmentVariableA(i->first.c_str(), i->second.c_str());
    }

    return curr_vars;
}
Exemplo n.º 10
0
Result<Environment> Environment::CreateForUser(const Handle& token, bool inherit, Trace& trace)
{
	trace < L"Environment::CreateForUser";
	Environment newEnvironment;
	LPVOID environment;
	if (!CreateEnvironmentBlock(&environment, token, inherit))
	{
		return Error(L"CreateEnvironmentBlock");
	}

	try
	{
		newEnvironment.CreateVariableMap(environment, trace);
	}
	catch (...)
	{
	}

	DestroyEnvironmentBlock(environment);
	return newEnvironment;
}
Result<Environment> Environment::CreateForUser(const Handle& token, bool inherit, Trace& trace)
{
	trace < L"Environment::CreateForUser";
	Environment newEnvironment;
	LPVOID environment;
	if (!CreateEnvironmentBlock(&environment, token, inherit))
	{
		return Result<Environment>(ErrorUtilities::GetErrorCode(), ErrorUtilities::GetLastErrorMessage(L"CreateEnvironmentBlock"));
	}

	try
	{
		newEnvironment.CreateVariableMap(environment, trace);
	}
	catch (...)
	{
	}

	DestroyEnvironmentBlock(environment);
	return newEnvironment;
}
Exemplo n.º 12
0
BOOL
MSWindowsWatchdog::doStartProcess(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa)
{
	// clear, as we're reusing process info struct
	ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));

	STARTUPINFO si;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = "winsta0\\Default"; // TODO: maybe this should be \winlogon if we have logonui.exe?
	si.hStdError = m_stdOutWrite;
	si.hStdOutput = m_stdOutWrite;
	si.dwFlags |= STARTF_USESTDHANDLES;

	LPVOID environment;
	BOOL blockRet = CreateEnvironmentBlock(&environment, userToken, FALSE);
	if (!blockRet) {
		LOG((CLOG_ERR "could not create environment block"));
		throw XArch(new XArchEvalWindows);
	}

	DWORD creationFlags = 
		NORMAL_PRIORITY_CLASS |
		CREATE_NO_WINDOW |
		CREATE_UNICODE_ENVIRONMENT;

	// re-launch in current active user session
	LOG((CLOG_INFO "starting new process"));
	BOOL createRet = CreateProcessAsUser(
		userToken, NULL, LPSTR(command.c_str()),
		sa, NULL, TRUE, creationFlags,
		environment, NULL, &si, &m_processInfo);

	DestroyEnvironmentBlock(environment);
	CloseHandle(userToken);

	return createRet;
}
std::shared_ptr<PROCESS_INFORMATION> LaunchProcess(wchar_t* commandline, DWORD sessionid){
	auto ProcessInfo = std::shared_ptr<PROCESS_INFORMATION>(new PROCESS_INFORMATION(), [=](PROCESS_INFORMATION* p){
		CloseHandle(p->hThread);
		CloseHandle(p->hProcess);
		delete p;
	});
	STARTUPINFO StartUPInfo;
	memset(&StartUPInfo, 0, sizeof(STARTUPINFO));
	memset(ProcessInfo.get(), 0, sizeof(PROCESS_INFORMATION));

	StartUPInfo.lpDesktop = L"Winsta0\\Winlogon";
	StartUPInfo.cb = sizeof(STARTUPINFO);
	HANDLE winloginhandle = NULL;
	PVOID	lpEnvironment = NULL;

	if (GetWinlogonHandle(&winloginhandle, sessionid)){
		if (CreateEnvironmentBlock(&lpEnvironment, winloginhandle, FALSE) == FALSE) lpEnvironment = NULL;
		SetLastError(0);
		CreateProcessAsUser(winloginhandle, NULL, commandline, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT | NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS, lpEnvironment, NULL, &StartUPInfo, ProcessInfo.get());
	}
	if (lpEnvironment) DestroyEnvironmentBlock(lpEnvironment);
	CloseHandle(winloginhandle);
	return ProcessInfo;
}
Exemplo n.º 14
0
BOOL InjectDll(DWORD dwPID, char *szDllName)  
{  
    HANDLE hProcess2 = NULL;  
    LPVOID pRemoteBuf = NULL;  
    FARPROC pThreadProc = NULL;  

	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	BOOL bResult = FALSE;
	DWORD dwSessionId = -1;
	DWORD winlogonPid = -1;
	HANDLE hUserToken,hUserTokenDup,hPToken,hProcess;
	DWORD dwCreationFlags;
	TCHAR wcQMountPath[256];
	TCHAR wcQMountArgs[256];

	memset(wcQMountPath,0,sizeof(wcQMountPath));
	memset(wcQMountArgs,0,sizeof(wcQMountArgs));

	//dwSessionId = WTSGetActiveConsoleSessionId();

	HMODULE hModuleKern = LoadLibrary( TEXT("KERNEL32.dll") );
	if( hModuleKern != NULL ) 
	{
		DWORD	(__stdcall *funcWTSGetActiveConsoleSessionId) (void);

		funcWTSGetActiveConsoleSessionId = (DWORD  (__stdcall *)(void))GetProcAddress( hModuleKern, "WTSGetActiveConsoleSessionId" );
		if( funcWTSGetActiveConsoleSessionId != NULL ) 
		{
			dwSessionId = funcWTSGetActiveConsoleSessionId();
		}
	}
	if( hModuleKern != NULL ) 
	{
		// ¥í©`¥É¤·¤¿DLL¤ò½â·Å
		FreeLibrary( hModuleKern );
	}
	OutputDebugStringA("LaunchAppIntoDifferentSession is called.\n");

	//
	// Find the winlogon process
	//
	PROCESSENTRY32 procEntry;

	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnap == INVALID_HANDLE_VALUE){
		return FALSE;
	}

	procEntry.dwSize = sizeof(PROCESSENTRY32);
	if (!Process32First(hSnap, &procEntry)){
		return FALSE;
	}

	do
	{
		if (stricmp(procEntry.szExeFile, "winlogon.exe") == 0)
		{
			//
			// We found a winlogon process...make sure it's running in the console session
			//
			DWORD winlogonSessId = 0;
			if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId){
				winlogonPid = procEntry.th32ProcessID;
				break;
			}
		}
	} while (Process32Next(hSnap, &procEntry));

	if (-1 == winlogonPid) {
	}



	//WTSQueryUserToken(dwSessionId,&hUserToken);
    BOOL    (__stdcall *funcWTSQueryUserToken) (ULONG, PHANDLE);
	HMODULE hModuleWTS = LoadLibrary( TEXT("Wtsapi32.dll") );
	if( hModuleWTS != NULL ) 
	{
		BOOL    (__stdcall *funcWTSQueryUserToken) (ULONG, PHANDLE);

		funcWTSQueryUserToken = (BOOL  (__stdcall *)(ULONG, PHANDLE))GetProcAddress( hModuleWTS, "WTSQueryUserToken" );
		if( funcWTSQueryUserToken != NULL ) 
		{
			funcWTSQueryUserToken(dwSessionId,&hUserToken);
		}
	}
	if( hModuleWTS != NULL ) 
	{
		// ¥í©`¥É¤·¤¿DLL¤ò½â·Å
		FreeLibrary( hModuleKern );
	}

	dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb= sizeof(STARTUPINFO);
	si.lpDesktop = "winsta0\\default";
	ZeroMemory(&pi, sizeof(pi));
	TOKEN_PRIVILEGES tp;
	LUID luid;
	hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid);

	if( !::OpenProcessToken(hProcess,
							TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY|TOKEN_DUPLICATE|
							TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID|TOKEN_READ|TOKEN_WRITE,
							&hPToken))
	{
		//OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]: OpenProcessToken(Error=%d)\n",GetLastError());
	}

	if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
	{
		//OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]:LookupPrivilegeValue.(Error=%d)\n",GetLastError());
	}

	tp.PrivilegeCount =1;
	tp.Privileges[0].Luid =luid;
	tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;

	DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup);
	int dup = GetLastError();

	//
	//Adjust Token privilege
	//
	SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)dwSessionId,sizeof(DWORD));

	if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL))
	{
		//OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]: AdjustTokenPrivileges.(Error=%d)\n",GetLastError());
	}

	if (GetLastError()== ERROR_NOT_ALL_ASSIGNED)
	{
		//OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]: Token does not have the provilege\n");
	}

	LPVOID pEnv =NULL;

	if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE)){
		dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
	}
	else
	{
		pEnv=NULL;
	}

    
    DWORD dwBufSize = strlen(szDllName)+1;  
    if ( !(hProcess2 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )  
    {  
        printf("[´íÎó] OpenProcess(%d) µ÷ÓÃʧ°Ü£¡´íÎó´úÂë: [%d]/n",   
        dwPID, GetLastError());  
        return FALSE;  
    }  
    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,   
                                MEM_COMMIT, PAGE_READWRITE);  
    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,   
                       dwBufSize, NULL);  
    pThreadProc = GetProcAddress(GetModuleHandle("kernel32.dl"),   
                                 "LoadLibraryA");  
    if( !MyCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf) )  
    {  
        printf("[´íÎó] CreateRemoteThread() µ÷ÓÃʧ°Ü£¡´íÎó´úÂë: [%d]/n", GetLastError());  
        return FALSE;  
    }  
    VirtualFreeEx(hProcess2, pRemoteBuf, 0, MEM_RELEASE);  
    CloseHandle(hProcess2);  

	CloseHandle(hProcess);
	CloseHandle(hUserToken);
	CloseHandle(hUserTokenDup);
	CloseHandle(hPToken);

    return TRUE;  
}  
Exemplo n.º 15
0
void
CMSWindowsRelauncher::mainLoop(void*)
{
	shutdownExistingProcesses();

	SendSas sendSasFunc = NULL;
	HINSTANCE sasLib = LoadLibrary("sas.dll");
	if (sasLib) {
		LOG((CLOG_DEBUG "found sas.dll"));
		sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
	}

	DWORD sessionId = -1;
	bool launched = false;

	SECURITY_ATTRIBUTES saAttr; 
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL; 

	if (!CreatePipe(&m_stdOutRead, &m_stdOutWrite, &saAttr, 0)) {
		throw XArch(new XArchEvalWindows());
	}

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	int failures = 0;

	while (m_running) {

		HANDLE sendSasEvent = 0;
		if (sasLib && sendSasFunc) {
			// can't we just create one event? seems weird creating a new
			// event every second...
			sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS");
		}

		DWORD newSessionId = getSessionId();

		bool running = false;
		if (launched) {

			DWORD exitCode;
			GetExitCodeProcess(pi.hProcess, &exitCode);
			running = (exitCode == STILL_ACTIVE);

			if (!running) {
				failures++;
				LOG((CLOG_INFO "detected application not running, pid=%d, failures=%d", pi.dwProcessId, failures));
				
				// increasing backoff period, maximum of 10 seconds.
				int timeout = (failures * 2) < 10 ? (failures * 2) : 10;
				LOG((CLOG_DEBUG "waiting, backoff period is %d seconds", timeout));
				ARCH->sleep(timeout);
				
				// double check, in case process started after we waited.
				GetExitCodeProcess(pi.hProcess, &exitCode);
				running = (exitCode == STILL_ACTIVE);
			}
			else {
				// reset failures when running.
				failures = 0;
			}
		}

		// only enter here when id changes, and the session isn't -1, which
		// may mean that there is no active session.
		bool sessionChanged = ((newSessionId != sessionId) && (newSessionId != -1));

		// relaunch if it was running but has stopped unexpectedly.
		bool stoppedRunning = (launched && !running);

		if (stoppedRunning || sessionChanged || m_commandChanged) {
			
			m_commandChanged = false;

			if (launched) {
				LOG((CLOG_DEBUG "closing existing process to make way for new one"));
				shutdownProcess(pi.hProcess, pi.dwProcessId, 20);
				launched = false;
			}

			// ok, this is now the active session (forget the old one if any)
			sessionId = newSessionId;

			SECURITY_ATTRIBUTES sa;
			ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));

			// get the token for the user in active session, which is the
			// one receiving input from mouse and keyboard.
			HANDLE userToken = getCurrentUserToken(sessionId, &sa);

			if (userToken != 0) {
				LOG((CLOG_DEBUG "got user token to launch new process"));

				std::string cmd = command();
				if (cmd == "") {
					// this appears on first launch when the user hasn't configured
					// anything yet, so don't show it as a warning, only show it as
					// debug to devs to let them know why nothing happened.
					LOG((CLOG_DEBUG "nothing to launch, no command specified."));
					continue;
				}

				// in case reusing process info struct
				ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

				STARTUPINFO si;
				ZeroMemory(&si, sizeof(STARTUPINFO));
				si.cb = sizeof(STARTUPINFO);
				si.lpDesktop = "winsta0\\default";
				si.hStdError = m_stdOutWrite;
				si.hStdOutput = m_stdOutWrite;
				si.dwFlags |= STARTF_USESTDHANDLES;

				LPVOID environment;
				BOOL blockRet = CreateEnvironmentBlock(&environment, userToken, FALSE);
				if (!blockRet) {
					LOG((CLOG_ERR "could not create environment block (error: %i)", 
						GetLastError()));
					continue;
				}
				else {

					DWORD creationFlags = 
						NORMAL_PRIORITY_CLASS |
						CREATE_NO_WINDOW |
						CREATE_UNICODE_ENVIRONMENT;

					// re-launch in current active user session
					LOG((CLOG_INFO "starting new process"));
					BOOL createRet = CreateProcessAsUser(
						userToken, NULL, LPSTR(cmd.c_str()),
						&sa, NULL, TRUE, creationFlags,
						environment, NULL, &si, &pi);

					DestroyEnvironmentBlock(environment);
					CloseHandle(userToken);

					if (!createRet) {
						LOG((CLOG_ERR "could not launch (error: %i)", GetLastError()));
						continue;
					}
					else {
						LOG((CLOG_DEBUG "launched in session %i (cmd: %s)", 
							sessionId, cmd.c_str()));
						launched = true;
					}
				}
			}
		}

		if (sendSasEvent) {
			// use SendSAS event to wait for next session.
			if (WaitForSingleObject(sendSasEvent, 1000) == WAIT_OBJECT_0 && sendSasFunc) {
				LOG((CLOG_DEBUG "calling SendSAS"));
				sendSasFunc(FALSE);
			}
			CloseHandle(sendSasEvent);
		}
		else {
			// check for session change every second.
			ARCH->sleep(1);
		}
	}

	if (launched) {
		LOG((CLOG_DEBUG "terminated running process on exit"));
		shutdownProcess(pi.hProcess, pi.dwProcessId, 20);
	}
	
	LOG((CLOG_DEBUG "relauncher main thread finished"));
}
Exemplo n.º 16
0
static void test_create_env(void)
{
    BOOL r;
    HANDLE htok;
    WCHAR * env1, * env2, * env3, * env4;
    char * st;
    int i, j;

    static const struct profile_item common_vars[] = {
        { "ALLUSERSPROFILE", { 1, 1, 0, 0 } },
        { "CommonProgramFiles", { 1, 1, 1, 1 } },
        { "ComSpec", { 1, 1, 0, 0 } },
        { "COMPUTERNAME", { 1, 1, 1, 1 } },
        { "NUMBER_OF_PROCESSORS", { 1, 1, 0, 0 } },
        { "OS", { 1, 1, 0, 0 } },
        { "PROCESSOR_ARCHITECTURE", { 1, 1, 0, 0 } },
        { "PROCESSOR_IDENTIFIER", { 1, 1, 0, 0 } },
        { "PROCESSOR_LEVEL", { 1, 1, 0, 0 } },
        { "PROCESSOR_REVISION", { 1, 1, 0, 0 } },
        { "SystemDrive", { 1, 1, 0, 0 } },
        { "SystemRoot", { 1, 1, 0, 0 } },
        { "windir", { 1, 1, 0, 0 } },
        { "ProgramFiles", { 1, 1, 0, 0 } },
        { 0, { 0, 0, 0, 0 } }
    };
    static const struct profile_item htok_vars[] = {
        { "PATH", { 1, 1, 0, 0 } },
        { "TEMP", { 1, 1, 0, 0 } },
        { "TMP", { 1, 1, 0, 0 } },
        { "USERPROFILE", { 1, 1, 0, 0 } },
        { 0, { 0, 0, 0, 0 } }
    };

    r = SetEnvironmentVariableA("WINE_XYZZY", "ZZYZX");
    expect(TRUE, r);

    r = CreateEnvironmentBlock(NULL, NULL, FALSE);
    expect(FALSE, r);

    r = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htok);
    expect(TRUE, r);

    r = CreateEnvironmentBlock(NULL, htok, FALSE);
    expect(FALSE, r);

    r = CreateEnvironmentBlock((LPVOID) &env1, NULL, FALSE);
    expect(TRUE, r);

    r = CreateEnvironmentBlock((LPVOID) &env2, htok, FALSE);
    expect(TRUE, r);

    r = CreateEnvironmentBlock((LPVOID) &env3, NULL, TRUE);
    expect(TRUE, r);

    r = CreateEnvironmentBlock((LPVOID) &env4, htok, TRUE);
    expect(TRUE, r);

    /* Test for common environment variables */
    i = 0;
    while (common_vars[i].name)
    {
        j = 0;
        r = get_env(env1, common_vars[i].name, &st);
        if (common_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, common_vars[i].name);
        else
            expect_env(TRUE, r, common_vars[i].name);
        j++;
        r = get_env(env2, common_vars[i].name, &st);
        if (common_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, common_vars[i].name);
        else
            expect_env(TRUE, r, common_vars[i].name);
        j++;
        r = get_env(env3, common_vars[i].name, &st);
        if (common_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, common_vars[i].name);
        else
            expect_env(TRUE, r, common_vars[i].name);
        j++;
        r = get_env(env4, common_vars[i].name, &st);
        if (common_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, common_vars[i].name);
        else
            expect_env(TRUE, r, common_vars[i].name);
        i++;
    }

    /* Test for environment variables with values that depends on htok */
    i = 0;
    while (htok_vars[i].name)
    {
        j = 0;
        r = get_env(env1, htok_vars[i].name, &st);
        if (htok_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, htok_vars[i].name);
        else
            expect_env(TRUE, r, htok_vars[i].name);
        j++;
        r = get_env(env2, htok_vars[i].name, &st);
        if (htok_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, htok_vars[i].name);
        else
            expect_env(TRUE, r, htok_vars[i].name);
        j++;
        r = get_env(env3, htok_vars[i].name, &st);
        if (htok_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, htok_vars[i].name);
        else
            expect_env(TRUE, r, htok_vars[i].name);
        j++;
        r = get_env(env4, htok_vars[i].name, &st);
        if (htok_vars[i].todo[j])
            todo_wine expect_env(TRUE, r, htok_vars[i].name);
        else
            expect_env(TRUE, r, htok_vars[i].name);
        i++;
    }

    r = get_env(env1, "WINE_XYZZY", &st);
    expect(FALSE, r);
    r = get_env(env2, "WINE_XYZZY", &st);
    expect(FALSE, r);
    r = get_env(env3, "WINE_XYZZY", &st);
    expect(TRUE, r);
    r = get_env(env4, "WINE_XYZZY", &st);
    expect(TRUE, r);
}
Exemplo n.º 17
0
bool ProcessStarter::Run(bool forceRun)
{
	OSVERSIONINFO version = {sizeof(OSVERSIONINFO)};

	GetVersionEx(&version);
	if (version.dwMajorVersion <= 5 && !forceRun) //dont need this on XP/Win2K
		return false;

	char winDir[260];
	GetSystemDirectoryA(winDir,sizeof(winDir));

	PHANDLE primaryToken = 0;
	try {
		if (version.dwMajorVersion <= 5) //win2K/XP
			primaryToken = GetCurrentUserTokenOld();
		else
			primaryToken = GetCurrentUserToken();
	} catch(std::exception &ex) {
		log << "exception :" << ex.what() << std::endl;
		}
    if (primaryToken == 0)
    {
		log << "primtok = 0" << std::endl;
        return false;
    }

    STARTUPINFOA StartupInfo;
    PROCESS_INFORMATION processInfo;
	memset(&StartupInfo,0,sizeof(StartupInfo));
    StartupInfo.cb = sizeof(StartupInfo);
#if 0
	std::string command = std::string("\"") + winDir + 
			"\\cmd.exe\" /C \""+ processPath_ + " " + arguments_ + "\"";
#else
    std::string command = "\"" + processPath_ + "\"";
    if (arguments_.length() != 0)
    {
        command += " " + arguments_;
    }
#endif
	log << "command:" << command << std::endl;

    void* lpEnvironment = NULL;
	if (!forceRun) {
		BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, primaryToken, FALSE);
		if (resultEnv == 0)
		{                                
			long nError = GetLastError();                                
		}
		log << "CreateEnvironmentBlock ok" << std::endl;
		}

    BOOL result = CreateProcessAsUserA(*primaryToken, 0, (LPSTR)(command.c_str()), 
		NULL,NULL,
		FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, 
		lpEnvironment, 0, &StartupInfo, &processInfo);

	log << "CreateProcessAsUserA " << result << " err 0x" 
		<< std::hex << std::setfill('0') << std::setw(8) << GetLastError() << std::endl;
	if (result != FALSE)
		log << "launched" << std::endl;
	else
		log << "didnt launch" << std::endl;
    if (!forceRun) 
		CloseHandle(primaryToken);
    return (result != FALSE);
}
Exemplo n.º 18
0
BOOL
WinLaunchChild(const wchar_t *exePath,
               int argc,
               wchar_t **argv,
               HANDLE userToken,
               HANDLE *hProcess)
{
  wchar_t *cl;
  BOOL ok;

  cl = MakeCommandLine(argc, argv);
  if (!cl) {
    return FALSE;
  }

  STARTUPINFOW si = {0};
  si.cb = sizeof(STARTUPINFOW);
  si.lpDesktop = L"winsta0\\Default";
  PROCESS_INFORMATION pi = {0};

  if (userToken == nullptr) {
    ok = CreateProcessW(exePath,
                        cl,
                        nullptr,  // no special security attributes
                        nullptr,  // no special thread attributes
                        FALSE, // don't inherit filehandles
                        0,     // creation flags
                        nullptr,  // inherit my environment
                        nullptr,  // use my current directory
                        &si,
                        &pi);
  } else {
    // Create an environment block for the process we're about to start using
    // the user's token.
    LPVOID environmentBlock = nullptr;
    if (!CreateEnvironmentBlock(&environmentBlock, userToken, TRUE)) {
      environmentBlock = nullptr;
    }

    ok = CreateProcessAsUserW(userToken,
                              exePath,
                              cl,
                              nullptr,  // no special security attributes
                              nullptr,  // no special thread attributes
                              FALSE,    // don't inherit filehandles
                              0,        // creation flags
                              environmentBlock,
                              nullptr,  // use my current directory
                              &si,
                              &pi);

    if (environmentBlock) {
      DestroyEnvironmentBlock(environmentBlock);
    }
  }

  if (ok) {
    if (hProcess) {
      *hProcess = pi.hProcess; // the caller now owns the HANDLE
    } else {
      CloseHandle(pi.hProcess);
    }
    CloseHandle(pi.hThread);
  } else {
    LPVOID lpMsgBuf = nullptr;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM |
                  FORMAT_MESSAGE_IGNORE_INSERTS,
                  nullptr,
                  GetLastError(),
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (LPTSTR) &lpMsgBuf,
                  0,
                  nullptr);
    wprintf(L"Error restarting: %s\n", lpMsgBuf ? static_cast<const wchar_t*>(lpMsgBuf) : L"(null)");
    if (lpMsgBuf)
      LocalFree(lpMsgBuf);
  }

  free(cl);

  return ok;
}
Exemplo n.º 19
0
/* returns TRUE if a user's environment was loaded; otherwise, FALSE.*/
BOOL
OwnerProfile::environment ( Env &env ) {

    dprintf ( D_FULLDEBUG, "In OwnerProfile::environment()\n" );

    priv_state  priv    = PRIV_UNKNOWN;
    PVOID       penv    = NULL;
    PWSTR       w_penv  = NULL,
                w_tmp   = NULL;
    PSTR        tmp     = NULL;    
    BOOL        created = FALSE,
                ok      = FALSE;

    __try {

        /* we must do the following as the user or Condor */
        priv = set_condor_priv ();

        /* if we are loading the user's profile, then overwrite 
        any existing environment variables with the values in the 
        user's profile (don't inherit anything from the global
        environment, as we will already have that at when we are 
        called) */
        created = CreateEnvironmentBlock ( 
            &penv, 
            user_token_, 
            FALSE ); /* we already have the current process env */
        ASSERT ( penv );

        dprintf ( 
            D_FULLDEBUG, 
            "OwnerProfile::environment: Loading %s while retrieving "
            "%s's environment (last-error = %u)\n",
            created ? "succeeded" : "failed", 
            user_name_,
            GetLastError () );

        if ( !created ) {
            __leave;
        }

        /* fill the environment with the user's environment values */
        dprintf ( D_FULLDEBUG, "Environment:\n" );
        w_penv = (PWSTR)penv;
        while ( '\0' != *w_penv ) { /* read: while not "\0\0' */
            tmp = ProduceAFromW ( w_penv );
            if ( tmp && strlen ( tmp ) > 0 ) {
                dprintf ( D_FULLDEBUG, "%s\n", tmp );
                env.SetEnv ( tmp );
                delete [] tmp;
            }
            w_penv += wcslen ( w_penv ) + 1;
        }

        /* if we've arrived here, then all it well */
        ok = TRUE;

    }
    __finally {

        /* rid ourselves of the user's environment information */
        if ( penv ) {
            if ( !DestroyEnvironmentBlock ( penv ) ) {
                dprintf ( 
                    D_ALWAYS, 
                    "OwnerProfile::environment: "
                    "DestroyEnvironmentBlock() failed "
                    "(last-error = %u)\n", 
                    GetLastError () );
            }
        }

        /* return to previous privilege level */
        set_priv ( priv );

    }

    return ok;

}
Exemplo n.º 20
0
int execute(const std::wstring& commandLine, const commandlineProcessor& options)
{
    wchar_t * environment = nullptr;
    HANDLE userToken = INVALID_HANDLE_VALUE;

    if (options.e)
    {
        OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &userToken);
        CreateEnvironmentBlock(
            reinterpret_cast<LPVOID *>(&environment),
            userToken,
            FALSE
        );
        CloseHandle(userToken);
    }


    BOOL noError;
    STARTUPINFO startupInfo;
    PROCESS_INFORMATION processInformation;
    ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
    startupInfo.dwFlags = STARTF_USESHOWWINDOW;
    startupInfo.wShowWindow = SW_HIDE;
    noError = CreateProcess(
        NULL,											//lpApplicationName
        const_cast<LPWSTR>(commandLine.c_str()),		//lpCommandLine
        NULL,											//lpProcessAttributes
        NULL,											//lpThreadAttributes
        FALSE,											//bInheritHandles
        CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,	//dwCreationFlags
        options.e ? environment : NULL,					//lpEnvironment
        NULL,											//lpCurrentDirectory
        &startupInfo,									//lpStartupInfo
        &processInformation								//lpProcessInformation
    );

    if(!noError)
    {
        return GetLastError();
    }
    
    DWORD exitCode = 0;
    
    if (options.w)
    {
        WaitForSingleObject(processInformation.hProcess, INFINITE);
        if (GetExitCodeProcess(processInformation.hProcess, &exitCode) == 0)
        {
            exitCode = (DWORD)-1;
        }
    }

    CloseHandle( processInformation.hProcess );
    CloseHandle( processInformation.hThread );
    if (options.e)
    {
        DestroyEnvironmentBlock(static_cast<LPVOID>(environment));
    }

    return (int) exitCode;
}
Exemplo n.º 21
0
BOOL CreateInteractiveProcess(DWORD dwSessionId,
                              PWSTR pszCommandLine, 
                              BOOL fWait, 
                              DWORD dwTimeout, 
                              DWORD *pExitCode)
{
    DWORD dwError = ERROR_SUCCESS;
    HANDLE hToken = NULL;
    LPVOID lpvEnv = NULL;
    wchar_t szUserProfileDir[MAX_PATH];
    DWORD cchUserProfileDir = ARRAYSIZE(szUserProfileDir);
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };
    DWORD dwWaitResult;

    // Obtain the primary access token of the logged-on user specified by the 
    // session ID.
    if (!WTSQueryUserToken(dwSessionId, &hToken))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Run the command line in the session that we found by using the default 
    // values for working directory and desktop.

    // This creates the default environment block for the user.
    if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Retrieve the path to the root directory of the user's profile.
    if (!GetUserProfileDirectory(hToken, szUserProfileDir, 
        &cchUserProfileDir))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Specify that the process runs in the interactive desktop.
    si.lpDesktop = L"winsta0\\default";

    // Launch the process.
    if (!CreateProcessAsUser(hToken, NULL, pszCommandLine, NULL, NULL, FALSE, 
        CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfileDir, &si, &pi))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    if (fWait)
    {
        // Wait for the exit of the process.
        dwWaitResult = WaitForSingleObject(pi.hProcess, dwTimeout);
        if (dwWaitResult == WAIT_OBJECT_0)
        {
            // If the process exits before timeout, get the exit code.
            GetExitCodeProcess(pi.hProcess, pExitCode);
        }
        else if (dwWaitResult == WAIT_TIMEOUT)
        {
            // If it times out, terminiate the process.
            TerminateProcess(pi.hProcess, IDTIMEOUT);
            *pExitCode = IDTIMEOUT;
        }
        else
        {
            dwError = GetLastError();
            goto Cleanup;
        }
    }
    else
    {
        *pExitCode = IDASYNC;
    }

Cleanup:

    // Centralized cleanup for all allocated resources.
    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }
    if (lpvEnv)
    {
        DestroyEnvironmentBlock(lpvEnv);
        lpvEnv = NULL;
    }
    if (pi.hProcess)
    {
        CloseHandle(pi.hProcess);
        pi.hProcess = NULL;
    }
    if (pi.hThread)
    {
        CloseHandle(pi.hThread);
        pi.hThread = NULL;
    }

    // Set the last error if something failed in the function.
    if (dwError != ERROR_SUCCESS)
    {
        SetLastError(dwError);
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
Exemplo n.º 22
0
static void test_create_env(void)
{
    BOOL r;
    HANDLE htok;
    WCHAR * env[4];
    char * st;
    int i, j;

    static const struct profile_item common_vars[] = {
        { "ComSpec", { 1, 1, 0, 0 } },
        { "COMPUTERNAME", { 1, 1, 1, 1 } },
        { "NUMBER_OF_PROCESSORS", { 1, 1, 0, 0 } },
        { "OS", { 1, 1, 0, 0 } },
        { "PROCESSOR_ARCHITECTURE", { 1, 1, 0, 0 } },
        { "PROCESSOR_IDENTIFIER", { 1, 1, 0, 0 } },
        { "PROCESSOR_LEVEL", { 1, 1, 0, 0 } },
        { "PROCESSOR_REVISION", { 1, 1, 0, 0 } },
        { "SystemDrive", { 1, 1, 0, 0 } },
        { "SystemRoot", { 1, 1, 0, 0 } },
        { "windir", { 1, 1, 0, 0 } }
    };
    static const struct profile_item common_post_nt4_vars[] = {
        { "ALLUSERSPROFILE", { 1, 1, 0, 0 } },
        { "CommonProgramFiles", { 1, 1, 1, 1 } },
        { "ProgramFiles", { 1, 1, 0, 0 } }
    };
    static const struct profile_item htok_vars[] = {
        { "PATH", { 1, 1, 0, 0 } },
        { "TEMP", { 1, 1, 0, 0 } },
        { "TMP", { 1, 1, 0, 0 } },
        { "USERPROFILE", { 1, 1, 0, 0 } }
    };

    r = SetEnvironmentVariableA("WINE_XYZZY", "ZZYZX");
    expect(TRUE, r);

    if (0)
    {
        /* Crashes on NT4 */
        r = CreateEnvironmentBlock(NULL, NULL, FALSE);
        expect(FALSE, r);
    }

    r = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htok);
    expect(TRUE, r);

    if (0)
    {
        /* Crashes on NT4 */
        r = CreateEnvironmentBlock(NULL, htok, FALSE);
        expect(FALSE, r);
    }

    r = CreateEnvironmentBlock((LPVOID) &env[0], NULL, FALSE);
    expect(TRUE, r);

    r = CreateEnvironmentBlock((LPVOID) &env[1], htok, FALSE);
    expect(TRUE, r);

    r = CreateEnvironmentBlock((LPVOID) &env[2], NULL, TRUE);
    expect(TRUE, r);

    r = CreateEnvironmentBlock((LPVOID) &env[3], htok, TRUE);
    expect(TRUE, r);

    /* Test for common environment variables (NT4 and higher) */
    for (i = 0; i < sizeof(common_vars)/sizeof(common_vars[0]); i++)
    {
        for (j = 0; j < 4; j++)
        {
            r = get_env(env[j], common_vars[i].name, &st);
            if (common_vars[i].todo[j])
                todo_wine expect_env(TRUE, r, common_vars[i].name);
            else
                expect_env(TRUE, r, common_vars[i].name);
        }
    }

    /* Test for common environment variables (post NT4) */
    if (!GetEnvironmentVariableA("ALLUSERSPROFILE", NULL, 0))
    {
        win_skip("Some environment variables are not present on NT4\n");
    }
    else
    {
        for (i = 0; i < sizeof(common_post_nt4_vars)/sizeof(common_post_nt4_vars[0]); i++)
        {
            for (j = 0; j < 4; j++)
            {
                r = get_env(env[j], common_post_nt4_vars[i].name, &st);
                if (common_post_nt4_vars[i].todo[j])
                    todo_wine expect_env(TRUE, r, common_post_nt4_vars[i].name);
                else
                    expect_env(TRUE, r, common_post_nt4_vars[i].name);
            }
        }
    }

    /* Test for environment variables with values that depends on htok */
    for (i = 0; i < sizeof(htok_vars)/sizeof(htok_vars[0]); i++)
    {
        for (j = 0; j < 4; j++)
        {
            r = get_env(env[j], htok_vars[i].name, &st);
            if (htok_vars[i].todo[j])
                todo_wine expect_env(TRUE, r, htok_vars[i].name);
            else
                expect_env(TRUE, r, htok_vars[i].name);
        }
    }

    r = get_env(env[0], "WINE_XYZZY", &st);
    expect(FALSE, r);
    r = get_env(env[1], "WINE_XYZZY", &st);
    expect(FALSE, r);
    r = get_env(env[2], "WINE_XYZZY", &st);
    expect(TRUE, r);
    r = get_env(env[3], "WINE_XYZZY", &st);
    expect(TRUE, r);
}
Exemplo n.º 23
0
void
CMSWindowsRelauncher::mainLoop(void*)
{
	SendSas sendSasFunc = NULL;
	HINSTANCE sasLib = LoadLibrary("sas.dll");
	if (sasLib) {
		LOG((CLOG_DEBUG "found sas.dll"));
		sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
	}

	DWORD sessionId = -1;
	bool launched = false;

	SECURITY_ATTRIBUTES saAttr; 
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL; 

	if (!CreatePipe(&m_stdOutRead, &m_stdOutWrite, &saAttr, 0)) {
		throw XArch(new XArchEvalWindows());
	}

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

	while (m_running) {

		HANDLE sendSasEvent = 0;
		if (sasLib && sendSasFunc) {
			// can't we just create one event? seems weird creating a new
			// event every second...
			sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS");
		}

		DWORD newSessionId = getSessionId();

		// only enter here when id changes, and the session isn't -1, which
		// may mean that there is no active session.
		if (((newSessionId != sessionId) && (newSessionId != -1)) || m_commandChanged) {
			
			m_commandChanged = false;

			if (launched) {
				LOG((CLOG_DEBUG "closing existing process to make way for new one"));
				shutdownProcess(pi, 10);
				launched = false;
			}

			// ok, this is now the active session (forget the old one if any)
			sessionId = newSessionId;

			SECURITY_ATTRIBUTES sa;
			ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));

			// get the token for the user in active session, which is the
			// one receiving input from mouse and keyboard.
			HANDLE userToken = getCurrentUserToken(sessionId, &sa);

			if (userToken != 0) {
				LOG((CLOG_DEBUG "got user token to launch new process"));

				std::string cmd = command();
				if (cmd == "") {
					LOG((CLOG_WARN "nothing to launch, no command specified."));
					continue;
				}

				// in case reusing process info struct
				ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

				STARTUPINFO si;
				ZeroMemory(&si, sizeof(STARTUPINFO));
				si.cb = sizeof(STARTUPINFO);
				si.lpDesktop = "winsta0\\default";
				si.hStdError = m_stdOutWrite;
				si.hStdOutput = m_stdOutWrite;
				si.dwFlags |= STARTF_USESTDHANDLES;

				LPVOID environment;
				BOOL blockRet = CreateEnvironmentBlock(&environment, userToken, FALSE);
				if (!blockRet) {
					LOG((CLOG_ERR "could not create environment block (error: %i)", 
						GetLastError()));
					continue;
				}
				else {

					DWORD creationFlags = 
						NORMAL_PRIORITY_CLASS |
						CREATE_NO_WINDOW |
						CREATE_UNICODE_ENVIRONMENT;

					// re-launch in current active user session
					BOOL createRet = CreateProcessAsUser(
						userToken, NULL, LPSTR(cmd.c_str()),
						&sa, NULL, TRUE, creationFlags,
						environment, NULL, &si, &pi);

					DestroyEnvironmentBlock(environment);
					CloseHandle(userToken);

					if (!createRet) {
						LOG((CLOG_ERR "could not launch (error: %i)", GetLastError()));
						continue;
					}
					else {
						LOG((CLOG_DEBUG "launched in session %i (cmd: %s)", 
							sessionId, cmd.c_str()));
						launched = true;
					}
				}
			}
		}

		if (sendSasEvent) {
			// use SendSAS event to wait for next session.
			if (WaitForSingleObject(sendSasEvent, 1000) == WAIT_OBJECT_0 && sendSasFunc) {
				LOG((CLOG_DEBUG "calling SendSAS"));
				sendSasFunc(FALSE);
			}
			CloseHandle(sendSasEvent);
		}
		else {
			// check for session change every second.
			ARCH->sleep(1);
		}
	}

	if (launched) {
		LOG((CLOG_DEBUG "terminated running process on exit"));
		shutdownProcess(pi, 10);
	}
}
Exemplo n.º 24
0
bool StartProcess(Settings& settings, HANDLE hCmdPipe)
{
	//Launching as one of:
	//1. System Account
	//2. Specified account (or limited account)
	//3. As current process

	DWORD gle = 0;

	BOOL bLoadedProfile = FALSE;
	PROFILEINFO profile = {0};
	profile.dwSize = sizeof(profile);
	profile.lpUserName = (LPWSTR)(LPCWSTR)settings.user;
	profile.dwFlags = PI_NOUI;

	if(false == GetUserHandle(settings, bLoadedProfile, profile, hCmdPipe))
		return false;

	PROCESS_INFORMATION pi = {0};
	STARTUPINFO si = {0};
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_SHOW;
	if(!BAD_HANDLE(settings.hStdErr))
	{
		si.hStdError = settings.hStdErr;
		si.hStdInput = settings.hStdIn;
		si.hStdOutput = settings.hStdOut;
		si.dwFlags |= STARTF_USESTDHANDLES;
#ifdef _DEBUG
		Log(L"DEBUG: Using redirected handles", false);
#endif
	}
#ifdef _DEBUG
	else
		Log(L"DEBUG: Not using redirected IO", false);
#endif

	CString path = StrFormat(L"\"%s\"", settings.app);
	if(FALSE == settings.appArgs.IsEmpty())
	{
		path += L" ";
		path += settings.appArgs;
	}

	LPCWSTR startingDir = NULL;
	if(FALSE == settings.workingDir.IsEmpty())
		startingDir = settings.workingDir;

	DWORD launchGLE = 0;

	CleanupInteractive ci = {0};

	if(settings.bInteractive || settings.bShowUIOnWinLogon)
	{
		BOOL b = PrepForInteractiveProcess(settings, &ci, settings.sessionToInteractWith);
		if(FALSE == b)
			Log(L"Failed to PrepForInteractiveProcess", true);

		if(NULL == si.lpDesktop)
			si.lpDesktop = L"WinSta0\\Default"; 
		if(settings.bShowUIOnWinLogon)
			si.lpDesktop = L"winsta0\\Winlogon";
		//Log(StrFormat(L"Using desktop: %s", si.lpDesktop), false);
		//http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx
		//indicates desktop names are case sensitive
	}
#ifdef _DEBUG
	Log(StrFormat(L"DEBUG: PAExec using desktop %s", si.lpDesktop == NULL ? L"{default}" : si.lpDesktop), false);
#endif

	DWORD dwFlags = CREATE_SUSPENDED | CREATE_NEW_CONSOLE;

	LPVOID pEnvironment = NULL;
	VERIFY(CreateEnvironmentBlock(&pEnvironment, settings.hUser, TRUE));
	if(NULL != pEnvironment)
		dwFlags |= CREATE_UNICODE_ENVIRONMENT;
#ifdef _DEBUG
	gle = GetLastError();
	Log(L"DEBUG: CreateEnvironmentBlock", gle);
#endif

	if(settings.bDisableFileRedirection)
		DisableFileRedirection();

	if(settings.bRunLimited)
		if(false == LimitRights(settings.hUser))
			return false;

	if(settings.bRunElevated)
		if(false == ElevateUserToken(settings.hUser))
			return false;

	CString user, domain;
	GetUserDomain(settings.user, user, domain);

#ifdef _DEBUG
	Log(StrFormat(L"DEBUG: U:%s D:%s P:%s bP:%d Env:%s WD:%s",
		user, domain, settings.password, settings.bDontLoadProfile,
		pEnvironment ? L"true" : L"null", startingDir ? startingDir : L"null"), false);
#endif

	BOOL bLaunched = FALSE;

	if(settings.bUseSystemAccount)
	{
		Log(StrFormat(L"PAExec starting process [%s] as Local System", path), false);

		if(BAD_HANDLE(settings.hUser))
			Log(L"Have bad user handle", true);

		EnablePrivilege(SE_IMPERSONATE_NAME);
		BOOL bImpersonated = ImpersonateLoggedOnUser(settings.hUser);
		if(FALSE == bImpersonated)
		{
			Log(L"Failed to impersonate", GetLastError());
			_ASSERT(bImpersonated);
		}
		EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME);
		EnablePrivilege(SE_INCREASE_QUOTA_NAME);
		bLaunched = CreateProcessAsUser(settings.hUser, NULL, path.LockBuffer(), NULL, NULL, TRUE, dwFlags, pEnvironment, startingDir, &si, &pi);
		launchGLE = GetLastError();
		path.UnlockBuffer();

#ifdef _DEBUG
		if(0 != launchGLE)
			Log(StrFormat(L"Launch (launchGLE=%u) params: user=[x%X] path=[%s] flags=[x%X], pEnv=[%s], dir=[%s], stdin=[x%X], stdout=[x%X], stderr=[x%X]",
						launchGLE, (DWORD)settings.hUser, path, dwFlags, pEnvironment ? L"{env}" : L"{null}", startingDir ? startingDir : L"{null}", 
						(DWORD)si.hStdInput, (DWORD)si.hStdOutput, (DWORD)si.hStdError), false);
#endif

		RevertToSelf();
	}
	else
	{
		if(FALSE == settings.user.IsEmpty()) //launching as a specific user
		{
			Log(StrFormat(L"PAExec starting process [%s] as %s", path, settings.user), false);

			if(false == settings.bRunLimited)
			{
				bLaunched = CreateProcessWithLogonW(user, domain.IsEmpty() ? NULL : domain, settings.password, settings.bDontLoadProfile ? 0 : LOGON_WITH_PROFILE, NULL, path.LockBuffer(), dwFlags, pEnvironment, startingDir, &si, &pi);
				launchGLE = GetLastError();
				path.UnlockBuffer();

#ifdef _DEBUG
				if(0 != launchGLE) 
					Log(StrFormat(L"Launch (launchGLE=%u) params: user=[%s] domain=[%s] prof=[x%X] path=[%s] flags=[x%X], pEnv=[%s], dir=[%s], stdin=[x%X], stdout=[x%X], stderr=[x%X]",
									launchGLE, user, domain, settings.bDontLoadProfile ? 0 : LOGON_WITH_PROFILE, 
									path, dwFlags, pEnvironment ? L"{env}" : L"{null}", startingDir ? startingDir : L"{null}", 
									(DWORD)si.hStdInput, (DWORD)si.hStdOutput, (DWORD)si.hStdError), false);
#endif
			}
			else
				bLaunched = FALSE; //force to run with CreateProcessAsUser so rights can be limited

			//CreateProcessWithLogonW can't be called from LocalSystem on Win2003 and earlier, so LogonUser/CreateProcessAsUser must be used. Might as well try for everyone
			if((FALSE == bLaunched) && !BAD_HANDLE(settings.hUser))
			{
#ifdef _DEBUG
				Log(L"DEBUG: Failed CreateProcessWithLogonW - trying CreateProcessAsUser", GetLastError());
#endif
				EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME);
				EnablePrivilege(SE_INCREASE_QUOTA_NAME);
				EnablePrivilege(SE_IMPERSONATE_NAME);
				BOOL bImpersonated = ImpersonateLoggedOnUser(settings.hUser);
				if(FALSE == bImpersonated)
				{
					Log(L"Failed to impersonate", GetLastError());
					_ASSERT(bImpersonated);
				}

				bLaunched = CreateProcessAsUser(settings.hUser, NULL, path.LockBuffer(), NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, pEnvironment, startingDir, &si, &pi);
				if(0 == GetLastError())
					launchGLE = 0; //mark as successful, otherwise return our original error
				path.UnlockBuffer();
#ifdef _DEBUG
				if(0 != launchGLE)
					Log(StrFormat(L"Launch (launchGLE=%u) params: user=[x%X] path=[%s] pEnv=[%s], dir=[%s], stdin=[x%X], stdout=[x%X], stderr=[x%X]",
									launchGLE, (DWORD)settings.hUser, path, pEnvironment ? L"{env}" : L"{null}", startingDir ? startingDir : L"{null}", 
									(DWORD)si.hStdInput, (DWORD)si.hStdOutput, (DWORD)si.hStdError), false);
#endif
				RevertToSelf();
			}
		}
		else
		{
			Log(StrFormat(L"PAExec starting process [%s] as current user", path), false);

			EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME);
			EnablePrivilege(SE_INCREASE_QUOTA_NAME);
			EnablePrivilege(SE_IMPERSONATE_NAME);

			if(NULL != settings.hUser)
				bLaunched = CreateProcessAsUser(settings.hUser, NULL, path.LockBuffer(), NULL, NULL, TRUE, dwFlags, pEnvironment, startingDir, &si, &pi);
			if(FALSE == bLaunched)
				bLaunched = CreateProcess(NULL, path.LockBuffer(), NULL, NULL, TRUE, dwFlags, pEnvironment, startingDir, &si, &pi);
			launchGLE = GetLastError();
	
//#ifdef _DEBUG
			if(0 != launchGLE)
				Log(StrFormat(L"Launch (launchGLE=%u) params: path=[%s] user=[%s], pEnv=[%s], dir=[%s], stdin=[x%X], stdout=[x%X], stderr=[x%X]",
					launchGLE, path, settings.hUser ? L"{non-null}" : L"{null}", pEnvironment ? L"{env}" : L"{null}", startingDir ? startingDir : L"{null}", 
					(DWORD)si.hStdInput, (DWORD)si.hStdOutput, (DWORD)si.hStdError), false);
//#endif
			path.UnlockBuffer();
		}
	}

	if(bLaunched)
	{
		if(gbInService)
			Log(L"Successfully launched", false);

		settings.hProcess = pi.hProcess;
		settings.processID = pi.dwProcessId;

		if(false == settings.allowedProcessors.empty())
		{
			DWORD sysMask = 0, procMask = 0;
			VERIFY(GetProcessAffinityMask(pi.hProcess, &procMask, &sysMask));
			procMask = 0;
			for(std::vector<WORD>::iterator itr = settings.allowedProcessors.begin(); settings.allowedProcessors.end() != itr; itr++)
			{
				DWORD bit = 1;
				bit = bit << (*itr - 1);
				procMask |= bit & sysMask;
			}
			VERIFY(SetProcessAffinityMask(pi.hProcess, procMask));
		}

		VERIFY(SetPriorityClass(pi.hProcess, settings.priority));
		ResumeThread(pi.hThread);
		VERIFY(CloseHandle(pi.hThread));
	}
	else
	{
		Log(StrFormat(L"Failed to start %s.", path), launchGLE);
		if((ERROR_ELEVATION_REQUIRED == launchGLE) && (false == gbInService))
			Log(L"HINT: PAExec probably needs to be \"Run As Administrator\"", false);
	}

	if(ci.bPreped)
		CleanUpInteractiveProcess(&ci);

	if(settings.bDisableFileRedirection)
		RevertFileRedirection();

	if(NULL != pEnvironment)
		DestroyEnvironmentBlock(pEnvironment);
	pEnvironment = NULL;

	if(bLoadedProfile)
		UnloadUserProfile(settings.hUser, profile.hProfile);

	if(!BAD_HANDLE(settings.hUser))
	{
		CloseHandle(settings.hUser);
		settings.hUser = NULL;
	}

	return bLaunched ? true : false;
}
Exemplo n.º 25
0
bool ProcessStarter::run( bool forceRun )
{
	OSVERSIONINFO version = {sizeof(OSVERSIONINFO)};

	GetVersionEx(&version);
	if ((version.dwMajorVersion == 5 && version.dwMinorVersion == 0 ) && !forceRun) { //dont need this on XP/Win2K 
		d->log << "not being forced to run .." << std::endl;
		return false;
		}

	PHANDLE primaryToken = 0;
	try {
		if ((version.dwMajorVersion == 5) && (version.dwMinorVersion == 0) ) //win2K
			primaryToken = d->GetCurrentUserTokenOld();
		else
			primaryToken = d->GetCurrentUserToken();
	} catch(std::exception &ex) {
		d->log << "exception :" << ex.what() << std::endl;
		}
    if (primaryToken == 0)
    {
		d->log << "primtok = 0" << std::endl;
		if (!forceRun) 
	        return false;

    }

	STARTUPINFO StartupInfo;
    PROCESS_INFORMATION processInfo;
	memset(&StartupInfo,0,sizeof(StartupInfo));
    StartupInfo.cb = sizeof(StartupInfo);
	if (version.dwMajorVersion <= 5)
		StartupInfo.lpDesktop = L"winsta0\\default";
#if 0
	char winDir[260];
	GetSystemDirectoryA(winDir,sizeof(winDir));
	QString command = QString( "\"%1\\cmd.exe\" /C \"%2 %3\"" )
		.arg( winDir, d->processPath, d->arguments.join( " " ) );
#else
	QString command = d->processPath;
	if( !d->arguments.isEmpty() )
		command += " " + d->arguments.join( " " );
#endif
	d->log << "command:'" << command.toStdString() << "'" << std::endl;

    void* lpEnvironment = NULL;
	if (!forceRun)
	{
		BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, *primaryToken, TRUE);
		if (resultEnv == 0)
			long nError = GetLastError();                                
		d->log << "CreateEnvironmentBlock ok" << std::endl;
	}

	BOOL result;
	if (!primaryToken)
	{
		result = CreateProcessW(0, (WCHAR*)command.utf16(),
			NULL,NULL,
			FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, 
			lpEnvironment, 0, &StartupInfo, &processInfo);
	}
	else
	{
		d->log << "creating as user " << std::endl;
		result = CreateProcessAsUserW(*primaryToken, 0, (WCHAR*)command.utf16(),
			NULL,NULL,
			FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, 
			lpEnvironment, 0, &StartupInfo, &processInfo);
	}

	if (result != FALSE)
		d->log << "launched PID=" << processInfo.dwProcessId << std::endl;
	else
	{
		d->log << "didnt launch" << std::endl;
		d->log << "CreateProcessAsUserW " << result << " err 0x"
			<< std::hex << std::setfill('0') << std::setw(8) << GetLastError() << std::endl;
	}
    if (!forceRun) 
		CloseHandle(primaryToken);
    return (result != FALSE);
}
Exemplo n.º 26
0
// create the child process with command line "-runas session -parent [parent process id]"
// the child process will run in the specified session
HANDLE CWinRobotService::CreateChildProcess(ULONG sid)
{
	TrackDebugOut;

	WCHAR szComd[MAX_PATH*2];
	WCHAR curpath[MAX_PATH];
	GetModuleFileNameW( 0, curpath, MAX_PATH );
	PathRemoveFileSpec(curpath);
	DWORD dwProcessId = 0;
	HANDLE hNewToken = NULL;
	HRESULT hr = S_OK;
	HWINSTA  hwinsta = NULL;
	HANDLE hToken= NULL;
	void* pEnvBlock = NULL;
	PROCESS_INFORMATION pi;
	ZeroMemory(&pi,sizeof(pi));
	DWORD errcode=0;

	try
	{
		DebugOutF(filelog::log_info,"attempt to CreateChildProcess %d",sid);
// 		HANDLE hCurProcess = 0;
// 
// 		DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(), GetCurrentProcess(), &hCurProcess, 
// 			0, TRUE, DUPLICATE_SAME_ACCESS);
#ifdef _WIN64
		swprintf(szComd,L"\"%s\\WinRobotHostx64.exe\" -runas session -parent %d",curpath,GetProcessId(GetCurrentProcess()));
#else
		swprintf(szComd,L"\"%s\\WinRobotHostx86.exe\" -runas session -parent %d",curpath,GetProcessId(GetCurrentProcess()));
#endif
		STARTUPINFOW si;
		ZeroMemory(&si, sizeof(STARTUPINFOW));
		si.cb= sizeof(STARTUPINFOW);

		DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS;

		si.lpDesktop = L"winsta0\\default";;

		INT  *pState = NULL;
		DWORD buflen = 0;
		ConnectActiveSession();

		if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken)){
			DebugOutF(filelog::log_error,"OpenProcessToken failed , error code = %d",GetLastError());
			throw E_UNEXPECTED;
		}
		// Duplicate the token because we need modify it
		if(!DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,0,SecurityAnonymous ,TokenPrimary ,&hNewToken)){
			errcode = GetLastError();
			DebugOutF(filelog::log_error,"DuplicateTokenEx failed , error code = %d",GetLastError());
			throw HRESULT_FROM_WIN32(errcode);
		}
		// change the token so that the process will be create in the new session
		if(!SetTokenInformation(hNewToken,TokenSessionId,&sid,sizeof(DWORD)))
		{
			errcode = GetLastError();
			DebugOutF(filelog::log_error,"SetTokenInformation failed , error code = %d",GetLastError());
			throw HRESULT_FROM_WIN32(errcode);
		}
 		if(!CreateEnvironmentBlock( &pEnvBlock, hToken, TRUE)){
 			DebugOutF(filelog::log_error,"CreateEnvironmentBlock Failed, error code = %d",GetLastError());
 		}else{
 			dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
 		}
		BOOL bCreate = FALSE;
		for(int i=0;i<5;i++)
		{
			if(!(bCreate = CreateProcessAsUserW(hNewToken,
				0,szComd,0,0,FALSE,dwCreationFlags ,pEnvBlock,curpath,&si,&pi )))
			{
				if(GetLastError() == 233){
					// change the token so that the process will be create in the new session
					sid = 0;
					if(!SetTokenInformation(hNewToken,TokenSessionId,&sid,sizeof(DWORD)))
					{
						errcode = GetLastError();
						DebugOutF(filelog::log_error,"SetTokenInformation failed , error code = %d",GetLastError());
						throw HRESULT_FROM_WIN32(errcode);
					}
					continue;
				}
				Sleep(300);
				continue;
			}
			else
			{
				break;
			}
		}
		if(bCreate)
		{
			DebugOutF(filelog::log_info,"CreateChildProcess on session %d ok",sid);
		}
		else
		{
			DebugOutF(filelog::log_error,"CreateProcessAsUser on session %d %s,%s,failed error code = %d"
				,sid,(char*)CW2A(szComd),(char*)CW2A(curpath),GetLastError());
		}
	}
	catch (HRESULT hr1)
	{
		hr = hr1;
	}

	if(hToken) CloseHandle(hToken);
	if(hNewToken)CloseHandle(hNewToken);
	if(pi.hThread){CloseHandle(pi.hThread);pi.hThread = 0;}
	if(pEnvBlock)DestroyEnvironmentBlock(pEnvBlock);
	return pi.hProcess;
}
Exemplo n.º 27
0
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// START the app as system 
BOOL
LaunchProcessWin(DWORD dwSessionId,bool preconnect)
{
  BOOL                 bReturn = FALSE;
  HANDLE               hToken;
  STARTUPINFO          StartUPInfo;
  PVOID                lpEnvironment = NULL;

  ZeroMemory(&StartUPInfo,sizeof(STARTUPINFO));
  ZeroMemory(&ProcessInfo,sizeof(PROCESS_INFORMATION));
  StartUPInfo.wShowWindow = SW_SHOW;
  //StartUPInfo.lpDesktop = "Winsta0\\Winlogon";
  StartUPInfo.lpDesktop = "Winsta0\\Default";
  StartUPInfo.cb = sizeof(STARTUPINFO);
  SetTBCPrivileges();
  pad2(preconnect);

  if ( GetSessionUserTokenWin(&hToken,dwSessionId) )
  {
      if ( CreateEnvironmentBlock(&lpEnvironment, hToken, FALSE) ) 
      {
      
		 SetLastError(0);
         if (CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo))
			{
				counter=0;
				bReturn = TRUE;
				DWORD error=GetLastError();
				#ifdef _DEBUG
					char			szText[256];
					sprintf(szText," ++++++ CreateProcessAsUser winlogon %d\n",error);
					OutputDebugString(szText);		
				#endif
			}
		 else
		 {
			 DWORD error=GetLastError();
			 #ifdef _DEBUG
					char			szText[256];
					sprintf(szText," ++++++ CreateProcessAsUser failed %d %d %d\n",error,kickrdp,counter);
					OutputDebugString(szText);		
			#endif
			if (error==233 && kickrdp==1)
					{
						counter++;
						if (counter>3)
							{
								#ifdef _DEBUG
								DWORD error=GetLastError();
								sprintf(szText," ++++++ error==233 win\n");
								SetLastError(0);
								OutputDebugString(szText);		
								#endif
								typedef BOOLEAN (WINAPI * pWinStationConnect) (HANDLE,ULONG,ULONG,PCWSTR,ULONG);
								typedef BOOL (WINAPI * pLockWorkStation)();
								HMODULE  hlibwinsta = LoadLibrary("winsta.dll"); 
								HMODULE  hlibuser32 = LoadLibrary("user32.dll");
								pWinStationConnect WinStationConnectF=NULL;
								pLockWorkStation LockWorkStationF=NULL;

								if (hlibwinsta)
								   {
									   WinStationConnectF=(pWinStationConnect)GetProcAddress(hlibwinsta, "WinStationConnectW"); 
								   }
								if (hlibuser32)
								   {
									   LockWorkStationF=(pLockWorkStation)GetProcAddress(hlibuser32, "LockWorkStation"); 
								   }
								if (WinStationConnectF!=NULL && LockWorkStationF!=NULL)
									{
											DWORD ID=0;
											if (lpfnWTSGetActiveConsoleSessionId.isValid()) ID=(*lpfnWTSGetActiveConsoleSessionId)();
											WinStationConnectF(0, 0, ID, L"", 0);
											LockWorkStationF();
									}
								Sleep(3000);
						}
					}
			else if (error==233)
			{
				CreateRemoteSessionProcess(dwSessionId,true,hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo);
				counter=0;
				bReturn = TRUE;
			}
		 }

         if (lpEnvironment) 
         {
            DestroyEnvironmentBlock(lpEnvironment);
         }

	  }//createenv
	  else
	  {
		  SetLastError(0);
         if (CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,DETACHED_PROCESS,NULL,NULL,&StartUPInfo,&ProcessInfo))
			{
				counter=0;
				bReturn = TRUE;
				DWORD error=GetLastError();
				#ifdef _DEBUG
					char			szText[256];
					sprintf(szText," ++++++ CreateProcessAsUser winlogon %d\n",error);
					OutputDebugString(szText);		
				#endif
			}
		 else
		 {
			 DWORD error=GetLastError();
			 #ifdef _DEBUG
					char			szText[256];
					sprintf(szText," ++++++ CreateProcessAsUser no env failed %d\n",error);
					OutputDebugString(szText);		
			#endif
			//Little trick needed, FUS sometimes has an unreachable logon session.
			 //Switch to USER B, logout user B
			 //The logon session is then unreachable
			 //We force the logon session on the console
			if (error==233 && kickrdp==1)
					{
						counter++;
						if (counter>3)
							{
								#ifdef _DEBUG
								DWORD error=GetLastError();
								sprintf(szText," ++++++ error==233 win\n");
								SetLastError(0);
								OutputDebugString(szText);		
								#endif
								typedef BOOLEAN (WINAPI * pWinStationConnect) (HANDLE,ULONG,ULONG,PCWSTR,ULONG);
								typedef BOOL (WINAPI * pLockWorkStation)();
								HMODULE  hlibwinsta = LoadLibrary("winsta.dll"); 
								HMODULE  hlibuser32 = LoadLibrary("user32.dll");
								pWinStationConnect WinStationConnectF=NULL;
								pLockWorkStation LockWorkStationF=NULL;

								if (hlibwinsta)
								   {
									   WinStationConnectF=(pWinStationConnect)GetProcAddress(hlibwinsta, "WinStationConnectW"); 
								   }
								if (hlibuser32)
								   {
									   LockWorkStationF=(pLockWorkStation)GetProcAddress(hlibuser32, "LockWorkStation"); 
								   }
								if (WinStationConnectF!=NULL && LockWorkStationF!=NULL)
									{
											DWORD ID=0;
											if (lpfnWTSGetActiveConsoleSessionId.isValid()) ID=(*lpfnWTSGetActiveConsoleSessionId)();
											WinStationConnectF(0, 0, ID, L"", 0);
											LockWorkStationF();
									}
								Sleep(3000);
						}
			}
			else if (error==233)
			{
				CreateRemoteSessionProcess(dwSessionId,true,hToken,NULL,app_path,NULL,NULL,FALSE,DETACHED_PROCESS,NULL,NULL,&StartUPInfo,&ProcessInfo);
				counter=0;
				bReturn = TRUE;
			}
	  }
        
	}  //getsession
	CloseHandle(hToken);
	}
  else
  {
	 #ifdef _DEBUG
	char			szText[256];
	DWORD error=GetLastError();
	sprintf(szText," ++++++ Getsessionusertokenwin failed %d\n",error);
	OutputDebugString(szText);		
	#endif

  }
    
    return bReturn;
}
Exemplo n.º 28
0
    bool LaunchProcess(const string16& cmdline,
        const LaunchOptions& options,
        ProcessHandle* process_handle)
    {
        STARTUPINFO startup_info = {};
        startup_info.cb = sizeof(startup_info);
        if(options.empty_desktop_name)
        {
            startup_info.lpDesktop = L"";
        }
        startup_info.dwFlags = STARTF_USESHOWWINDOW;
        startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW;
        PROCESS_INFORMATION process_info;

        DWORD flags = 0;

        if(options.job_handle)
        {
            flags |= CREATE_SUSPENDED;

            // If this code is run under a debugger, the launched process is
            // automatically associated with a job object created by the debugger.
            // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this.
            flags |= CREATE_BREAKAWAY_FROM_JOB;
        }

        if(options.as_user)
        {
            flags |= CREATE_UNICODE_ENVIRONMENT;
            void* enviroment_block = NULL;

            if(!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE))
            {
                return false;
            }

            BOOL launched = CreateProcessAsUser(options.as_user, NULL,
                const_cast<wchar_t*>(cmdline.c_str()),
                NULL, NULL, options.inherit_handles, flags,
                enviroment_block, NULL, &startup_info,
                &process_info);
            DestroyEnvironmentBlock(enviroment_block);
            if(!launched)
            {
                return false;
            }
        }
        else
        {
            if(!CreateProcess(NULL,
                const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL,
                options.inherit_handles, flags, NULL, NULL,
                &startup_info, &process_info))
            {
                return false;
            }
        }

        if(options.job_handle)
        {
            if(0 == AssignProcessToJobObject(options.job_handle, process_info.hProcess))
            {
                LOG(ERROR) << "Could not AssignProcessToObject.";
                KillProcess(process_info.hProcess, kProcessKilledExitCode, true);
                return false;
            }

            ResumeThread(process_info.hThread);
        }

        // Handles must be closed or they will leak.
        CloseHandle(process_info.hThread);

        if(options.wait)
        {
            WaitForSingleObject(process_info.hProcess, INFINITE);
        }

        // If the caller wants the process handle, we won't close it.
        if(process_handle)
        {
            *process_handle = process_info.hProcess;
        }
        else
        {
            CloseHandle(process_info.hProcess);
        }
        return true;
    }
Exemplo n.º 29
0
static DWORD service_start_process(struct service_entry *service_entry, HANDLE *process)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    LPWSTR path = NULL;
    DWORD size;
    BOOL r;

    service_lock_exclusive(service_entry);

    if (!env)
    {
        HANDLE htok;

        if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htok))
            CreateEnvironmentBlock(&env, htok, FALSE);

        if (!env)
            WINE_ERR("failed to create services environment\n");
    }

    size = ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,NULL,0);
    path = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
    if (!path)
    {
        service_unlock(service_entry);
        return ERROR_NOT_ENOUGH_SERVER_MEMORY;
    }
    ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,path,size);

    if (service_entry->config.dwServiceType == SERVICE_KERNEL_DRIVER)
    {
        static const WCHAR winedeviceW[] = {'\\','w','i','n','e','d','e','v','i','c','e','.','e','x','e',' ',0};
        WCHAR system_dir[MAX_PATH];
        DWORD type, len;

        GetSystemDirectoryW( system_dir, MAX_PATH );
        if (is_win64)
        {
            if (!GetBinaryTypeW( path, &type ))
            {
                HeapFree( GetProcessHeap(), 0, path );
                service_unlock(service_entry);
                return GetLastError();
            }
            if (type == SCS_32BIT_BINARY) GetSystemWow64DirectoryW( system_dir, MAX_PATH );
        }

        len = strlenW( system_dir ) + sizeof(winedeviceW)/sizeof(WCHAR) + strlenW(service_entry->name);
        HeapFree( GetProcessHeap(), 0, path );
        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
        {
            service_unlock(service_entry);
            return ERROR_NOT_ENOUGH_SERVER_MEMORY;
        }
        lstrcpyW( path, system_dir );
        lstrcatW( path, winedeviceW );
        lstrcatW( path, service_entry->name );
    }

    ZeroMemory(&si, sizeof(STARTUPINFOW));
    si.cb = sizeof(STARTUPINFOW);
    if (!(service_entry->config.dwServiceType & SERVICE_INTERACTIVE_PROCESS))
    {
        static WCHAR desktopW[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n','\\','D','e','f','a','u','l','t',0};
        si.lpDesktop = desktopW;
    }

    service_entry->status.dwCurrentState = SERVICE_START_PENDING;

    service_unlock(service_entry);

    r = CreateProcessW(NULL, path, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi);
    HeapFree(GetProcessHeap(),0,path);
    if (!r)
    {
        service_lock_exclusive(service_entry);
        service_entry->status.dwCurrentState = SERVICE_STOPPED;
        service_unlock(service_entry);
        return GetLastError();
    }

    service_entry->status.dwProcessId = pi.dwProcessId;
    service_entry->process = pi.hProcess;
    *process = pi.hProcess;
    CloseHandle( pi.hThread );

    return ERROR_SUCCESS;
}
Exemplo n.º 30
0
//Function to run a process as active user from windows service
bool ActiveUserAndRun(std::wstring sUser, std::wstring sPassword, std::wstring sDomain, std::wstring sCommand)
{
	bool bResult = false;

	HANDLE hImpersonationToken = NULL;
	int nTick = ::GetTickCount();
	if (LoginBasedOnUserAccount(sUser, sPassword, sDomain, hImpersonationToken) == false)
	{
		std::cout << "Cannot login toolbox server" << std::endl;
		return false;
	}

	std::cout << "Take tickcount: " << (::GetTickCount() - nTick) << std::endl;
	// raise priv
	//enable_privs(hImpersonationToken);

	std::cout << "Before DuplicateTokenEx " << std::endl;
	HANDLE hUserToken = NULL;

	if (!DuplicateTokenEx(hImpersonationToken,
		//0,
		//MAXIMUM_ALLOWED,
		TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS | MAXIMUM_ALLOWED,
		NULL,
		SecurityImpersonation,
		TokenPrimary,
		&hUserToken))
	{
		//log error
		std::cout << "DuplicateTokenEx, error: " << ::GetLastError() << std::endl;
		return false;
	}

	std::cout << "DuplicateTokenEx successfully" << std::endl;

	STARTUPINFO StartupInfo = {0};  
	PROCESS_INFORMATION processInfo = {0};  

	StartupInfo.cb = sizeof(STARTUPINFO);  
	//std::string command = "HRAUnsolicitedAdapter.exe";
	LPVOID lpEnvironment = NULL;
	if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, TRUE))  
	{  
		std::cout << "CreateEnvironmentBlock failed! Error: " << ::GetLastError() << std::endl;
		return false;
	}  

	bResult = CreateProcessAsUser(  
		hUserToken,   
		0,   
		(LPWSTR)sCommand.c_str(),   
		NULL,   
		NULL,   
		FALSE,   
		NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT,  
		lpEnvironment, // __in_opt    LPVOID lpEnvironment,  
		0,   
		&StartupInfo,   
		&processInfo);  


	DestroyEnvironmentBlock(lpEnvironment);

	CloseHandle(hImpersonationToken);
	CloseHandle(hUserToken);

	RevertToSelf();

	// log off


	std::cout << "WTSFreeMemory done" << std::endl;

	return bResult;
}