void limitMem( size_t limit ) { static HANDLE hJob = NULL; JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo; jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY; jobInfo.ProcessMemoryLimit = limit? limit*MByte : 2*MByte*1024; if (NULL == hJob) { if (NULL == (hJob = CreateJobObject(NULL, NULL))) { REPORT("Can't assign create job object: %ld\n", GetLastError()); exit(1); } if (0 == AssignProcessToJobObject(hJob, GetCurrentProcess())) { REPORT("Can't assign process to job object: %ld\n", GetLastError()); exit(1); } } if (0 == SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) { REPORT("Can't set limits: %ld\n", GetLastError()); exit(1); } }
BOOL CreateBuilderJob(PCTSTR appName, PTSTR cmdLine, PCTSTR workDir, H2BOperation& op) { BOOL ret = TRUE; DWORD err = ERROR_SUCCESS; HANDLE job = CreateJobObject(NULL, NULL); if( job ) { JOBOBJECT_BASIC_LIMIT_INFORMATION jobLimit = { }; jobLimit.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS; jobLimit.ActiveProcessLimit = 1; if( SetInformationJobObject(job, JobObjectBasicLimitInformation, &jobLimit, sizeof(jobLimit)) ) { if( ! CreateBuilderProcess(job, appName, cmdLine, workDir, op) ) err = GetLastError(); } if( err == ERROR_CANCELLED ) TerminateJobObject(job, ERROR_CANCELLED); CloseHandle(job); } if( err != ERROR_SUCCESS ) { SetLastError(err); ret = FALSE; } return ret; }
bool JobbedProcessManager::spawn() { HANDLE handle; STARTUPINFO si = {sizeof(STARTUPINFO), 0}; PROCESS_INFORMATION pi; if (!szUsername) return false; if (!CreatePipe(&si.hStdInput, &handle, nullptr, 0)) throw WindowsException("CreatePipe stdin"); hStdin = handle; if (!CreatePipe(&handle, &si.hStdOutput, nullptr, 0)) throw WindowsException("CreatePipe stdout"); hStdout = handle; if (!CreatePipe(&handle, &si.hStdError, nullptr, 0)) throw WindowsException("CreatePipe stderr"); hStderr = handle; si.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; if (!CreateProcessWithLogonW(szUsername, L".", szPassword, 0, szExecutable, szCmdLine, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB | CREATE_UNICODE_ENVIRONMENT, szEnvBlock, szDirectory, &si, &pi)) throw WindowsException("CreateProcessWithLogonW"); CloseHandle(si.hStdInput); CloseHandle(si.hStdOutput); CloseHandle(si.hStdError); hProcess = pi.hProcess; if (!(handle = SearchForJobByService(hProcess, L"seclogon"))) throw WindowsException("Failed to find job", 0); hJob = handle; if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &extLimits, sizeof extLimits)) throw WindowsException("SetInformationJobObject JobObjectExtendedLimitInformation"); if (!SetInformationJobObject(hJob, JobObjectBasicUIRestrictions, &uiLimits, sizeof uiLimits)) throw WindowsException("SetInformationJobObject JobObjectBasicUIRestrictions"); LARGE_INTEGER liFreq; QueryPerformanceFrequency(&liFreq); qpc_freq = 1.0 / liFreq.QuadPart; QueryPerformanceCounter(&liStart); ResumeThread(pi.hThread); CloseHandle(pi.hThread); if (!(handle = CreateThread(nullptr, 0, s_ShockerProc, this, 0, nullptr))) throw WindowsException("CreateThread"); hShocker = handle; return true; }
JobObject::JobObject(void) : m_hJobObject(NULL) { HANDLE jobObject = CreateJobObject(NULL, NULL); if((jobObject != NULL) && (jobObject != INVALID_HANDLE_VALUE)) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobExtendedLimitInfo; memset(&jobExtendedLimitInfo, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); memset(&jobExtendedLimitInfo.BasicLimitInformation, 0, sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION)); jobExtendedLimitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; if(SetInformationJobObject(jobObject, JobObjectExtendedLimitInformation, &jobExtendedLimitInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))) { m_hJobObject = jobObject; } else { qWarning("Failed to set job object information!"); CloseHandle(jobObject); } } else { qWarning("Failed to create the job object!"); } }
/* This could be interesting to expose in public API */ static void _g_test_watcher_add_pid (GPid pid) { static gsize started = 0; HANDLE job; if (g_once_init_enter (&started)) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; job = CreateJobObjectW (NULL, NULL); memset (&info, 0, sizeof (info)); info.BasicLimitInformation.LimitFlags = 0x2000 /* JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE */; if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info, sizeof (info))) g_warning ("Can't enable JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: %s", g_win32_error_message (GetLastError())); g_once_init_leave (&started,(gsize)job); } job = (HANDLE)started; if (!AssignProcessToJobObject(job, pid)) g_warning ("Can't assign process to job: %s", g_win32_error_message (GetLastError())); }
void CJobObject::SetExtendedLimit(const JOBOBJECT_EXTENDED_LIMIT_INFORMATION& pLimit) { static BOOL bAlreadySet = FALSE; BOOL bRet; if (bAlreadySet == FALSE) { JOBOBJECT_END_OF_JOB_TIME_INFORMATION EndOfJobTimeAction; EndOfJobTimeAction.EndOfJobTimeAction = JOB_OBJECT_POST_AT_END_OF_JOB; bRet = SetInformationJobObject(GetHandle(), JobObjectEndOfJobTimeInformation, (PVOID) &EndOfJobTimeAction, sizeof(JOBOBJECT_END_OF_JOB_TIME_INFORMATION)); } bRet = SetInformationJobObject(GetHandle(), JobObjectExtendedLimitInformation, (PVOID) &pLimit, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); if (bRet == 0) { throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } }
//-------------------------------------------------------------------------------- bool CJob::SetGroupAffinityInfo( nsCodeQOR::CTLRef< CJob::sGroupAffinity > GroupAffinity, unsigned int uiCount ) { _WINQ_FCONTEXT( "CJob::SetGroupAffinityInfo" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectGroupInformationEx, GroupAffinity.operator nsWin32::CJob::sGroupAffinity *(), uiCount * sizeof( sGroupAffinity ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetGroupInfo( nsCodeQOR::CTLRef< unsigned short > GroupInfo, unsigned int uiCount ) { _WINQ_FCONTEXT( "CJob::SetGroupInfo" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectGroupInformation, GroupInfo.operator unsigned short *(), uiCount * sizeof( unsigned short ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetCPURateControlInfo( CJob::sJobObjectCPURateControlInformation& CPURateControlInformation ) { _WINQ_FCONTEXT( "CJob::SetCPURateControlInfo" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectCpuRateControlInformation, &CPURateControlInformation, sizeof( sJobObjectCPURateControlInformation ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetCompletionPortInfo( CJob::sJobObjectAssociateCompletionPort& AssociateCompletionPort ) { _WINQ_FCONTEXT( "CJob::SetCompletionPortInfo" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectAssociateCompletionPortInformation, &AssociateCompletionPort, sizeof( sJobObjectAssociateCompletionPort ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetEndOfJobTimeInfo( CJob::sJobObjectEndOfJobTimeInformation& EndOfJobTimeInformation ) { _WINQ_FCONTEXT( "CJob::SetEndOfJobTimeInfo" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectEndOfJobTimeInformation, &EndOfJobTimeInformation, sizeof( sJobObjectEndOfJobTimeInformation ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetUILimits( CJob::sJobObjectBasicUIRestrictions& UIRestrictions ) { _WINQ_FCONTEXT( "CJob::SetUILimits" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectBasicUIRestrictions, &UIRestrictions, sizeof( sJobObjectBasicUIRestrictions ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetNotificationLimitInformation( nsCodeQOR::CTLRef< CJob::sJobObjectNotificationLimitInformation > NotificationLimitInformation ) { _WINQ_FCONTEXT( "CJob::SetNotificationLimitInformation" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectNotificationLimitInformation, &NotificationLimitInformation, sizeof( sJobObjectNotificationLimitInformation ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//-------------------------------------------------------------------------------- bool CJob::SetBasicLimitInformation( nsCodeQOR::CTLRef< CJob::sJobObjectBasicLimitInformation > BasicLimitInformation ) { _WINQ_FCONTEXT( "CJob::SetBasicLimitInformation" ); bool bResult = false; __QOR_PROTECT { bResult = SetInformationJobObject( JobObjectBasicLimitInformation, BasicLimitInformation.operator nsWin32::CJob::sJobObjectBasicLimitInformation *(), sizeof( sJobObjectBasicLimitInformation ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
/// <summary> /// Creates a console object and starts the child process </summary> /// /// <param name="ac"> /// Uninitialized console object </param> /// <param name="tzClientPath"> /// Path to client, in an inject environment this should not be relative </param> /// /// <returns> /// If child could be created </returns> BOOL ImAllocConsole(OUT IM_CONSOLE* ac, IN const TCHAR* tzClientPath) { SecureZeroMemory(ac->tzClientPipe, MAX_NAME); // generate a random name (tmpnam has a forward slash and is not necessarily alphanumeric) for (register size_t i = 0; i < rand() % MAX_NAME; ++i) { ac->tzClientPipe[i] = rand() % 26 + 'A'; // make random letter ac->tzClientPipe[i] ^= rand() % 1 << 5; // randomly toggle 0x20 (upper/lowercase) } { // create job object and set information JOBOBJECT_EXTENDED_LIMIT_INFORMATION joELI; ac->hJob = CreateJobObject(NULL, ac->tzClientPipe); if (ac->hJob == NULL) return FALSE; joELI.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if(!SetInformationJobObject(ac->hJob, JobObjectExtendedLimitInformation, &joELI, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION))) { CloseHandle(ac->hJob), ac->hJob = NULL; return FALSE; } } { // create child process SECURITY_ATTRIBUTES sa = {0}; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; // sa.lpSecurityDescriptor = NULL; if (!CreatePipe(&ac->hRead, &ac->hWrite, &sa, BUFSIZ)) { CloseHandle(ac->hJob), ac->hJob = NULL; return FALSE; } STARTUPINFO siCon = {0}; PROCESS_INFORMATION piCon = {0}; siCon.cb = sizeof(siCon); siCon.hStdInput = ac->hRead; siCon.dwFlags |= STARTF_USESTDHANDLES; if (!CreateProcess(tzClientPath, NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB | CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &siCon, &piCon)) { CloseHandle(ac->hJob), ac->hJob = NULL; return FALSE; } DuplicateHandle(GetCurrentProcess(), piCon.hProcess, GetCurrentProcess(), &ac->hChildProcess, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(piCon.hThread); CloseHandle(piCon.hProcess); } return AssignProcessToJobObject(ac->hJob, ac->hChildProcess); }
void Job::applyRestrictions() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION limits; memset(&limits,0,sizeof limits); limits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | /* Not supported by Windows 2000 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | */ JOB_OBJECT_LIMIT_PRIORITY_CLASS; limits.BasicLimitInformation.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS; if (processesLimit) { limits.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS; limits.BasicLimitInformation.ActiveProcessLimit = 1; } if (timeLimit > 0) { limits.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PROCESS_TIME; limits.BasicLimitInformation.PerProcessUserTimeLimit.QuadPart = timeLimit; } if (memoryLimit > 0) { limits.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PROCESS_MEMORY; limits.ProcessMemoryLimit = memoryLimit; } tryApi(_T("SetInformationJobObject"), SetInformationJobObject(hJob,JobObjectExtendedLimitInformation,&limits,sizeof limits) != 0); JOBOBJECT_BASIC_UI_RESTRICTIONS ui; ui.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS | JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_GLOBALATOMS | JOB_OBJECT_UILIMIT_HANDLES | JOB_OBJECT_UILIMIT_READCLIPBOARD | JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD; tryApi(_T("SetInformationJobObject"), SetInformationJobObject(hJob,JobObjectBasicUIRestrictions,&ui,sizeof ui) != 0); }
void CJobObject::AssignCompletionPort() { CMutex::CEnter MutexEnter(m_Mutex); BOOL bRet; JOBOBJECT_ASSOCIATE_COMPLETION_PORT ObjectInfo; m_pCompletionPort = new CJobIoCompletionPort(this, 0, 0, INFINITE); ObjectInfo.CompletionKey = 0; ObjectInfo.CompletionPort = m_pCompletionPort->GetHandle(); bRet = SetInformationJobObject(GetHandle(), JobObjectAssociateCompletionPortInformation, &ObjectInfo, sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT)); if (bRet == 0) { throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } }
HANDLE EngineProcess::mainJob() { QMutexLocker locker(&s_mutex); if (s_job) return s_job; s_job = CreateJobObject(NULL, NULL); JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; memset(&jeli, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; SetInformationJobObject(s_job, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)); return s_job; }
int main( int argc , char* argv[] ) { #if defined(WIN32) && defined(MAX_MEMORY_GB) if( MAX_MEMORY_GB>0 ) { SIZE_T peakMemory = 1; peakMemory <<= 30; peakMemory *= MAX_MEMORY_GB; printf( "Limiting memory usage to %.2f GB\n" , float( peakMemory>>30 ) ); HANDLE h = CreateJobObject( NULL , NULL ); AssignProcessToJobObject( h , GetCurrentProcess() ); JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_JOB_MEMORY; jeli.JobMemoryLimit = peakMemory; if( !SetInformationJobObject( h , JobObjectExtendedLimitInformation , &jeli , sizeof( jeli ) ) ) fprintf( stderr , "Failed to set memory limit\n" ); }
//-------------------------------------------------------------------------------- bool CJob::SetUILimitExitWindows( bool bLimit ) { _WINQ_FCONTEXT( "CJob::SetUILimitExitWindows" ); bool bResult = false; __QOR_PROTECT { sJobObjectBasicUIRestrictions UILimits = GetUILimits(); if( bLimit ) { UILimits.UIRestrictionsClass |= eJobObjectUILimit_ExitWindows; } else { UILimits.UIRestrictionsClass &= (~eJobObjectUILimit_ExitWindows); } bResult = SetInformationJobObject( JobObjectBasicUIRestrictions, &UILimits, sizeof( sJobObjectBasicUIRestrictions ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
void runner::set_allow_breakaway(bool allow) { if (allow_breakaway == allow) { return; } if (main_job_object == handle_default_value) { main_job_object = CreateJobObject(NULL, NULL); AssignProcessToJobObject(main_job_object, GetCurrentProcess()); } JOBOBJECT_EXTENDED_LIMIT_INFORMATION extended_limit_information; memset(&extended_limit_information, 0, sizeof(extended_limit_information)); if (allow) { extended_limit_information.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; } if (!SetInformationJobObject(main_job_object, JobObjectExtendedLimitInformation, &extended_limit_information, sizeof(extended_limit_information))) { DWORD le = GetLastError(); return; } allow_breakaway = allow; }
Job::Job() { millisecondsIdle = 0; processesLimit = false; timeLimit = 0; memoryLimit = 0; cpuUsageIdle = 0; idlenessLimit = 0; std::_stringstream tmp; tmp << JOB_OBJECT_NAME; tmp << GetTickCount(); name = tmp.str(); qualifiedname = JOB_OBJECT_NAMESPACE; qualifiedname.append(name); hJob = CreateJobObject(NULL,qualifiedname.c_str()); tryApi(_T("CreateJobObject"), hJob != NULL); JOBOBJECT_ASSOCIATE_COMPLETION_PORT portInfo; portInfo.CompletionPort = port.handle(); portInfo.CompletionKey = NULL; tryApi(_T("SetInformationJobObject"), SetInformationJobObject(hJob,JobObjectAssociateCompletionPortInformation,&portInfo,sizeof portInfo) != 0); processTimeCounter = perfQuery.addCounter( PerformanceQuery::getPerformanceObjectNameByIndex(PerformanceQuery::INDEX_JOB_OBJECT), _T(""),name, PerformanceQuery::getPerformanceObjectNameByIndex(PerformanceQuery::INDEX_THIS_PERIOD_MSEC_PROCESSOR) ); elapsedTimeCounter = perfQuery.addCounter( PerformanceQuery::getPerformanceObjectNameByIndex(PerformanceQuery::INDEX_SYSTEM), _T(""),_T(""), PerformanceQuery::getPerformanceObjectNameByIndex(PerformanceQuery::INDEX_SYSTEM_UPTIME) ); elapsedTimeCounter.setFormatFlags(elapsedTimeCounter.getFormatFlags() | PDH_FMT_1000); memoryUsageCounter = perfQuery.addCounter( PerformanceQuery::getPerformanceObjectNameByIndex(PerformanceQuery::INDEX_JOB_OBJECT_DETAILS), name,PerformanceQuery::INSTANCE_TOTAL, PerformanceQuery::getPerformanceObjectNameByIndex(PerformanceQuery::INDEX_PAGEFILE_BYTES) ); }
static void uv__init_global_job_handle(void) { /* Create a job object and set it up to kill all contained processes when * it's closed. Since this handle is made non-inheritable and we're not * giving it to anyone, we're the only process holding a reference to it. * That means that if this process exits it is closed and all the processes * it contains are killed. All processes created with uv_spawn that are not * spawned with the UV_PROCESS_DETACHED flag are assigned to this job. * * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the * processes that we explicitly add are affected, and *their* subprocesses * are not. This ensures that our child processes are not limited in their * ability to use job control on Windows versions that don't deal with * nested jobs (prior to Windows 8 / Server 2012). It also lets our child * processes created detached processes without explicitly breaking away * from job control (which uv_spawn doesn't, either). */ SECURITY_ATTRIBUTES attr; JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; memset(&attr, 0, sizeof attr); attr.bInheritHandle = FALSE; memset(&info, 0, sizeof info); info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); if (uv_global_job_handle_ == NULL) uv_fatal_error(GetLastError(), "CreateJobObjectW"); if (!SetInformationJobObject(uv_global_job_handle_, JobObjectExtendedLimitInformation, &info, sizeof info)) uv_fatal_error(GetLastError(), "SetInformationJobObject"); }
ActivePet::ActivePet(wchar_t* user_password, std::wstring petname, FileEventLoop* files) : m_petname(petname), m_files(files), m_session(INVALID_HANDLE_VALUE), m_profile(INVALID_HANDLE_VALUE), m_job(CreateJobObject(NULL, NULL)), m_next_editable_name(1), m_ticks_while_invisible(0) { // Create a new logon session for the pet. std::wstring petRegistryPath = Constants::registryPets() + L"\\" + m_petname; RegKey petkey = RegKey::HKCU.open(petRegistryPath); std::wstring accountName = petkey.getValue(L"accountName"); std::wstring accountRegistryPath = Constants::registryAccounts() + L"\\" + accountName; RegKey accountKey = RegKey::HKCU.open(accountRegistryPath); std::wstring password = accountKey.getValue(L"password"); if (!LogonUser(accountName.c_str(), NULL, password.c_str(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_session)) { printf("LogonUser() failed: %d\n", GetLastError()); return; } // Tweak the Winsta0 and desktop ACLs to allow the pet to create windows. auto_buffer<PSID> logon_sid = GetLogonSID(m_session.get()); if (NULL == logon_sid.get()) { return; } auto_close<HWINSTA, &::CloseWindowStation> winsta0(OpenWindowStation(L"winsta0", FALSE, READ_CONTROL | WRITE_DAC)); if (NULL == winsta0.get()) { printf("OpenWindowStation() failed: %d\n", GetLastError()); return; } if (!AddAceToWindowStation(winsta0.get(), logon_sid.get())) { printf("AddAceToWindowStation() failed: %d", GetLastError()); return; } auto_close<HDESK, &::CloseDesktop> desktop(OpenDesktop(L"default", 0, FALSE, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS)); if (NULL == desktop.get()) { printf("OpenDesktop() failed: %d\n", GetLastError()); return; } if (!AddAceToDesktop(desktop.get(), logon_sid.get())) { printf("AddAceToDesktop() failed: %d\n", GetLastError()); return; } // Load the pet account's registry hive. wchar_t account[128] = {}; wcsncpy(account, accountName.c_str(), 128); PROFILEINFO profile = { sizeof(PROFILEINFO), 0, account }; if (!LoadUserProfile(m_session.get(), &profile)) { printf("LoadUserProfile() failed: %d\n", GetLastError()); return; } m_profile = profile.hProfile; // Initialize the pet job. if (NULL == m_job.get()) { printf("CreateJobObject() failed: %d\n", GetLastError()); return; } JOBOBJECT_BASIC_UI_RESTRICTIONS buir = { JOB_OBJECT_UILIMIT_HANDLES }; if (!SetInformationJobObject(m_job.get(), JobObjectBasicUIRestrictions, &buir, sizeof buir)) { printf("SetInformationJobObject() failed: %d\n", GetLastError()); } // Some apps fail to launch without access to the desktop window. if (!UserHandleGrantAccess(GetDesktopWindow(), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } // Give apps access to all the standard cursors. if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_ARROW), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_IBEAM), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_WAIT), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_CROSS), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_UPARROW), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZE), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_ICON), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENWSE), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENESW), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZEWE), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENS), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZEALL), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_NO), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_HAND), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_APPSTARTING), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_HELP), m_job.get(), TRUE)) { printf("UserHandleGrantAccess() failed: %d\n", GetLastError()); } // Setup the use records for the printers. std::set<std::wstring> servers; RegKey printers = RegKey::HKCU.open(L"Printers\\Connections"); for (int i = 0; true; ++i) { RegKey printer = printers.getSubKey(i); if (!printer.isGood()) { break; } std::wstring server = printer.getValue(L"Server"); if (servers.count(server) == 0) { std::wstring resource = server + L"\\IPC$"; auto_array<wchar_t> remote(resource.length() + 1); lstrcpy(remote.get(), resource.c_str()); USE_INFO_2 use = {}; use.ui2_remote = remote.get(); use.ui2_domainname = _wgetenv(L"USERDOMAIN"); use.ui2_username = _wgetenv(L"USERNAME");; use.ui2_password = user_password; use.ui2_asg_type = USE_WILDCARD; auto_impersonation impersonate(m_session.get()); DWORD arg_error; NET_API_STATUS error = NetUseAdd(NULL, 2, (BYTE*)&use, &arg_error); if (error) { printf("NetUseAdd() failed: %d\n", error); } else { servers.insert(server); } } } // Add the message handlers. //m_requestFolderPath = accountKey.getValue(Constants::petDataPathName()) + Constants::requestPath(); m_requestFolderPath = Constants::requestsPath(Constants::polarisDataPath(Constants::userProfilePath(accountName))); m_dispatcher = new MessageDispatcher(m_requestFolderPath); m_files->watch(m_requestFolderPath, m_dispatcher); m_dispatcher->add("sendmail",makeSendMailHandler()); // TODO m_dispatcher->add("GetOpenFileNameA", makeGetOpenFileNameAHandler(this)); m_dispatcher->add("GetOpenFileNameW", makeGetOpenFileNameWHandler(this)); m_dispatcher->add("GetClipboardData", makeGetClipboardDataHandler()); }
static intptr_t do_spawnv(rktio_t *rktio, const char *command, int argc, const char * const *argv, int exact_cmdline, intptr_t sin, intptr_t sout, intptr_t serr, int *pid, int new_process_group, int chain_termination_here_to_child, void *env, const char *wd) { intptr_t i, l, len = 0; int use_jo; intptr_t cr_flag; char *cmdline; wchar_t *cmdline_w, *wd_w, *command_w; STARTUPINFOW startup; PROCESS_INFORMATION info; if (exact_cmdline) { cmdline = (char *)argv[1]; } else { for (i = 0; i < argc; i++) { len += strlen(argv[i]) + 1; } cmdline = malloc(len); len = 0; for (i = 0; i < argc; i++) { l = strlen(argv[i]); memcpy(cmdline + len, argv[i], l); cmdline[len + l] = ' '; len += l + 1; } --len; cmdline[len] = 0; } memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); startup.dwFlags = STARTF_USESTDHANDLES; startup.hStdInput = (HANDLE)sin; startup.hStdOutput = (HANDLE)sout; startup.hStdError = (HANDLE)serr; /* If none of the stdio handles are consoles, specifically create the subprocess without a console: */ if (!rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdInput) && !rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdOutput) && !rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdError)) cr_flag = CREATE_NO_WINDOW; else cr_flag = 0; if (new_process_group) cr_flag |= CREATE_NEW_PROCESS_GROUP; cr_flag |= CREATE_UNICODE_ENVIRONMENT; use_jo = chain_termination_here_to_child; if (use_jo) { /* Use a job object to ensure that the new process will be terminated if this process ends for any reason (including a crash) */ if (!rktio->process_job_object) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; rktio->process_job_object = CreateJobObject(NULL, NULL); memset(&jeli, 0, sizeof(jeli)); jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; SetInformationJobObject(rktio->process_job_object, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)); } } cmdline_w = WIDE_PATH_copy(cmdline); if (!exact_cmdline) free(cmdline); wd_w = WIDE_PATH_copy(wd); command_w = WIDE_PATH_temp(command); if (cmdline_w && wd_w && command_w && CreateProcessW(command_w, cmdline_w, NULL, NULL, 1 /*inherit*/, cr_flag, env, wd_w, &startup, &info)) { if (use_jo) AssignProcessToJobObject(rktio->process_job_object, info.hProcess); CloseHandle(info.hThread); *pid = info.dwProcessId; free(cmdline_w); free(wd_w); return (intptr_t)info.hProcess; } else { if (cmdline_w) free(cmdline_w); if (wd_w) free(wd_w); return -1; } }
BOOL Go(const char *commandLine) { HANDLE stdInRead, stdInWrite; if (!CreatePipes(&stdInRead, &stdInWrite)) return FALSE; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); siStartInfo.hStdInput = stdInRead; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; siStartInfo.wShowWindow = SW_HIDE; siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; // Create the child process. if (!CreateProcess(NULL, const_cast<char *>(commandLine), // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited CREATE_BREAKAWAY_FROM_JOB, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO pointer &piProcInfo)) // receives PROCESS_INFORMATION { return FALSE; } HANDLE ghJob = CreateJobObject( NULL, NULL); JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if( ghJob == NULL || SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)) == FALSE) { std::cerr << "Error initializing close-process job"; return 1; } if (!AssignProcessToJobObject( ghJob, piProcInfo.hProcess)) { DWORD error = GetLastError(); std::cerr << "AssignProcessToJobObject failed: " << error << std::endl; return FALSE; } // Close handles to the child process and its primary thread. // Some applications might keep these handles to monitor the status // of the child process, for example. CloseHandle(piProcInfo.hThread); MonitorProcessClose(piProcInfo.hProcess); WriteToPipe(stdInWrite, piProcInfo.hProcess); CloseHandle(piProcInfo.hProcess); CloseHandle(stdInRead); CloseHandle(stdInWrite); return 0; }
/* Uninstall NSIS */ MSIDLLEXPORT UninstallNsisInstallation( MSIHANDLE hInstall ) { DWORD rv = ERROR_SUCCESS; // lookup the NSISUNINSTALL property value LPTSTR cNsisUninstall = _T("NSISUNINSTALL"); HANDLE hIo = NULL; DWORD dwSize = 0; LPTSTR strPathUninst = NULL; HANDLE hJob = NULL; STARTUPINFO sInfo; PROCESS_INFORMATION pInfo; pInfo.hProcess = NULL; pInfo.hThread = NULL; rv = MsiGetProperty( hInstall, cNsisUninstall, _T(""), &dwSize ); if(rv != ERROR_MORE_DATA) goto _cleanup; strPathUninst = new TCHAR[ ++dwSize ]; rv = MsiGetProperty( hInstall, cNsisUninstall, strPathUninst, &dwSize ); if(rv != ERROR_SUCCESS) goto _cleanup; // Create a process for the uninstaller sInfo.cb = sizeof(sInfo); sInfo.lpReserved = NULL; sInfo.lpDesktop = _T(""); sInfo.lpTitle = _T("Foo"); sInfo.dwX = 0; sInfo.dwY = 0; sInfo.dwXSize = 0; sInfo.dwYSize = 0; sInfo.dwXCountChars = 0; sInfo.dwYCountChars = 0; sInfo.dwFillAttribute = 0; sInfo.dwFlags = 0; sInfo.wShowWindow = 0; sInfo.cbReserved2 = 0; sInfo.lpReserved2 = 0; sInfo.hStdInput = 0; sInfo.hStdOutput = 0; sInfo.hStdError = 0; if(!CreateProcess( strPathUninst, _T("Uninstall /S"), NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sInfo, &pInfo)) { pInfo.hProcess = NULL; pInfo.hThread = NULL; rv = 40; goto _cleanup; }; // Create a job object to contain the NSIS uninstall process tree JOBOBJECT_ASSOCIATE_COMPLETION_PORT acp; acp.CompletionKey = 0; hJob = CreateJobObject(NULL, _T("NSISUninstallObject")); if(!hJob) { rv = 41; goto _cleanup; } hIo = CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0); if(!hIo) { rv = 42; goto _cleanup; } acp.CompletionPort = hIo; SetInformationJobObject( hJob, JobObjectAssociateCompletionPortInformation, &acp, sizeof(acp)); AssignProcessToJobObject( hJob, pInfo.hProcess ); ResumeThread( pInfo.hThread ); DWORD a,b,c; for(;;) { if(!GetQueuedCompletionStatus(hIo, &a, (PULONG_PTR) &b, (LPOVERLAPPED *) &c, INFINITE)) { Sleep(1000); continue; } if(a == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) { break; } } rv = ERROR_SUCCESS; _cleanup: if(hIo) CloseHandle(hIo); if(pInfo.hProcess) CloseHandle( pInfo.hProcess ); if(pInfo.hThread) CloseHandle( pInfo.hThread ); if(hJob) CloseHandle(hJob); if(strPathUninst) delete[] strPathUninst; if(rv != ERROR_SUCCESS) { ShowMsiError( hInstall, ERR_NSS_FAILED, rv ); } return rv; }
bool WindowsJob::setInformation(JOBOBJECTINFOCLASS infoClass, LPVOID lpInfo, DWORD cbInfoLength) { return !!SetInformationJobObject(jobHandle_, infoClass, lpInfo, cbInfoLength); }
bool AI::init(int engine) { bool engine_started = false; bool b64bit = isOS64Bit(); bool jobSuccess = false; m_engine = engine; memset(m_engine_path, 0, sizeof(m_engine_path)); // set up the security attributes m_sa.bInheritHandle = true; m_sa.lpSecurityDescriptor = NULL; m_sa.nLength = sizeof(SECURITY_ATTRIBUTES); // setup job to kill the child process when calling process terminates m_hJob = CreateJobObject(NULL, NULL); if(m_hJob != NULL){ m_jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; jobSuccess = SetInformationJobObject(m_hJob, JobObjectExtendedLimitInformation, &m_jeli, sizeof(m_jeli)); } // open a pipe to the AI engine if(!CreatePipe(&m_child_stdin, &m_hWrite, &m_sa, 0)){ throw std::runtime_error("CreatePipe - stdin"); return false; } if(!CreatePipe(&m_hRead, &m_child_stdout, &m_sa, 0)){ throw std::runtime_error("CreatePipe - stdout"); cleanup(); return false; } // prepare to launch the process GetStartupInfo(&m_si); m_si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; m_si.wShowWindow = SW_HIDE; m_si.hStdOutput = m_child_stdout; m_si.hStdError = m_child_stdout; m_si.hStdInput = m_child_stdin; for(;!engine_started;){ switch(m_engine){ case ENGINE_HOUDINI: if(b64bit){ strcpy(m_engine_path, "Data/Engines/Houdini_x64.exe"); checkProcess("Houdini_x64.exe"); } else{ strcpy(m_engine_path, "Data/Engines/Houdini_x86.exe"); checkProcess("Houdini_x86.exe"); } break; case ENGINE_STOCKFISH: if(b64bit){ strcpy(m_engine_path, "Data/Engines/Stockfish_x64.exe"); checkProcess("Stockfish_x64.exe"); } else{ strcpy(m_engine_path, "Data/Engines/Stockfish_x86.exe"); checkProcess("Stockfish_x86.exe"); } break; case ENGINE_CRITTER: if(b64bit){ strcpy(m_engine_path, "Data/Engines/Critter_x64.exe"); checkProcess("Critter_x64.exe"); } else{ strcpy(m_engine_path, "Data/Engines/Critter_x86.exe"); checkProcess("Critter_x86.exe"); } break; case ENGINE_CUSTOM: strcpy(m_engine_path, "Data/Engines/Custom.exe"); break; default: throw std::runtime_error("No valid engine found"); cleanup(); return false; } // attempt to launch the process engine_started = CreateProcess(m_engine_path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &m_si, &m_pi); if(!engine_started){ if(engine > 0) engine = 0; else ++engine; continue; } break; } // assign the job to the process if(jobSuccess){ jobSuccess = AssignProcessToJobObject(m_hJob, m_pi.hProcess); } // change states //m_active = true; //m_thinking = true; // set process priority to below normal to prevent destruction of the CPU SetPriorityClass(m_pi.hProcess, BELOW_NORMAL_PRIORITY_CLASS); // set AI to active if(engine_started){ m_active = true; // start the state machine thread (void)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&InitThread, this, 0, 0); } return true; }
int main(int argc, char** argv) { enum { envbufsize = 1024*32 ,exebufsize = 1024 ,cmdbufsize = envbufsize }; char *envbuf, *sep, *resbuf, *cmdbuf; DWORD len, exitCode; STARTUPINFO si; PROCESS_INFORMATION pi; DIE_IF_FALSE( (envbuf = malloc(envbufsize)) ); DIE_IF_FALSE( (cmdbuf = malloc(cmdbufsize)) ); *cmdbuf = 0; DIE_IF_FALSE( GetEnvironmentVariable("PATH", envbuf, envbufsize) ); dbg_printf("env: %s\n", envbuf); DIE_IF_FALSE( GetModuleFileName(0, cmdbuf, exebufsize) ); dbg_printf("curdir: %s\n", cmdbuf); DIE_IF_FALSE( (sep = strrchr(cmdbuf, '\\')) ); *(sep+1) = 0; strcat(cmdbuf, GDB_TO_PYTHON_REL_DIR); dbg_printf("sep: %s\n", cmdbuf); len = strlen(envbuf)+strlen(cmdbuf) +1 /* for envronment separator */ +1; /* for zero-terminator */ DIE_IF_FALSE( (resbuf = malloc(len)) ); DIE_IF_FALSE( (snprintf(resbuf, len, "%s;%s", cmdbuf, envbuf) > 0) ); dbg_printf("PATH: %s\n", resbuf); DIE_IF_FALSE( SetEnvironmentVariable("PATH", resbuf) ); *(sep+1) = 0; strcat(cmdbuf, PYTHONHOME_REL_DIR); dbg_printf("PYTHONHOME: %s\n", cmdbuf); DIE_IF_FALSE( SetEnvironmentVariable("PYTHONHOME", cmdbuf) ); *(sep+1) = 0; strcat(cmdbuf, GDB_EXECUTABLE_ORIG_FILENAME" "); if ( argc > 1 ) { for ( ++argv; *argv; ++argv ) { len = strlen(cmdbuf); snprintf(cmdbuf+len, cmdbufsize-len, "%s ", *argv); } } dbg_printf("cmd: %s\n", cmdbuf); HANDLE ghJob = CreateJobObject(NULL, "Gdb-Wrapper\0"/*NULL*/); if ( ghJob == NULL ) { dbg_printf("Could not create job object\n"); } else { JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; // Configure all child processes associated with the job to terminate when the last handle to the job is closed jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if ( SetInformationJobObject(ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)) == 0 ) { dbg_printf("Could not SetInformationJobObject\n"); } } memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags |= STARTF_USESTDHANDLES; si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); memset(&pi, 0, sizeof(pi)); DIE_IF_FALSE( CreateProcess( 0 // exe name ,cmdbuf // command line ,0 // process security attributes ,0 // primary thread security attributes ,TRUE // handles are inherited ,0 // creation flags ,0 // use parent's environment ,0 // use parent's current directory ,&si // STARTUPINFO pointer ,&pi // receives PROCESS_INFORMATION ) ); if ( ghJob != NULL && AssignProcessToJobObject(ghJob, pi.hProcess) == 0 ) { dbg_printf("Could not AssignProcessToObject\n"); } // Do not handle Ctrl-C in the wrapper SetConsoleCtrlHandler(NULL, TRUE); WaitForSingleObject(pi.hProcess, INFINITE); DIE_IF_FALSE( GetExitCodeProcess(pi.hProcess, &exitCode) ); if ( ghJob != NULL ) CloseHandle(ghJob); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); free(envbuf); free(resbuf); free(cmdbuf); dbg_printf("exiting with exitCode %d", exitCode); return exitCode; }