void ThreadPool::StartThreads(const u32 num) { _numThreads += num; for (u32 i = (u32)_threads.size(); i < _numThreads; ++i) { _threads.emplace_back([this, i] { tlog::debug() << StrFormat("Worker thread {0} started.", i); while (true) { std::unique_lock<std::mutex> lock{_taskQueueMutex}; // look for a work item while (i < _numThreads && _taskQueue.empty()) { //__LOG_DBG(MSG_THREADS, "Thread {0} is waiting for a task.", i); // if there are none wait for notification _workerCondition.wait(lock); } if (i >= _numThreads) break; std::function<void()> task{std::move(_taskQueue.front())}; _taskQueue.pop_front(); // Unlock the lock, so we can process the task without blocking other threads lock.unlock(); try { task(); } catch (const Exception& e) { e.Log(); } _numTasksInSystem--; { std::unique_lock<std::mutex> lock{_systemBusyMutex}; if (_numTasksInSystem == 0) _systemBusyCondition.notify_all(); } } tlog::debug() << StrFormat("Worker thread {0} stopped.", i); }); } }
HRESULT CDBStepNC::ExecuteSelectSql(CString tszSQL, StringTable &szColumnTable, StringTable &szDataTable) { USES_CONVERSION; CCommand< CDynamicStringAccessor > m_QueryCommand; HRESULT hr; hr = m_QueryCommand.Open( m_session, tszSQL ); if( FAILED( hr ) ) return hr; hr = m_QueryCommand.MoveFirst(); if( FAILED( hr ) ) return hr; int j=0; while( SUCCEEDED( hr ) && hr != DB_S_ENDOFROWSET ) { for( size_t i = 1; i < m_QueryCommand.GetColumnCount( ); i++ ) { OutputDebugString(StrFormat( "Column %d [%S]= %s\n", i, m_QueryCommand.GetColumnName( i ), m_QueryCommand.GetString( i ) )); szDataTable(j,i-1)=m_QueryCommand.GetString( i ); if(j==0) szColumnTable(0,i)=W2T(_bstr_t(m_QueryCommand.GetColumnName( i ))); } hr = m_QueryCommand.MoveNext( ); j++; } errors: return hr; }
long CAgentCfg::WriteDevicesFile(std::string xmlFile, std::string destFolder) { std::string contents; contents+="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; contents+="<MTConnectDevices xmlns=\"urn:mtconnect.org:MTConnectDevices:1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:mtconnect.org:MTConnectDevices:1.1 http://www.mtconnect.org/schemas/MTConnectDevices_1.1.xsd\">\n"; contents+=StrFormat("<Header bufferSize=\"130000\" instanceId=\"1\" creationTime=\"%s\" sender=\"local\" version=\"1.1\"/>\n", GetTimeStamp().c_str()); contents+="<Devices>\n"; // Check all machine names unique // Generate Devices.xml file with all devices in it. for(UINT i=0; i<names.size(); i++) { std::string config = GetFanucDeviceXml(_fanucconfigs[i]); // ReadXmlDevicesFile(devices[i]); ReplaceAll(config,"####", names[i]); config=ReplaceOnce(config,"name=\"NNNNNN\"","name=\""+names[i]+"\""); contents+=config+"\n"; } contents+="</Devices>\n"; contents+="</MTConnectDevices>\n"; if(!xmlFile.empty()) WriteFile(destFolder + "\\" + xmlFile , contents); return 0; }
long CAgentCfg::WriteAgentCfgFile(std::string cfgfile, std::string xmlFile, std::string destFolder) { // Generate agent.cfg file with all devices in it. std::string cfg; cfg= "Devices = " + xmlFile + "\n"; cfg+="Port = " + StrFormat("%d",_agenthttpport) + "\n"; cfg+="ServiceName = " + _serviceName + "\n"; // MTConnectAgent\n"; cfg+="CheckpointFrequency=10000\n"; cfg+="AllowPut=true\n"; cfg+="Adapters \n{\n"; for(UINT i=0; i<devices.size(); i++) { if(ports[i]!="0") { cfg+="\t"+names[i] + "\n"; cfg+="\t{\n"; cfg+="\t\tHost = " + ips[i] + "\n"; cfg+="\t\tPort = " + ports[i] + "\n"; cfg+="\t\tDeviceXml = " + ExtractFiletitle(devices[i]) + "\n"; cfg+="\t}\n"; } } cfg+="}\n"; cfg+="# Logger Configuration\n"; cfg+="logger_config\n"; cfg+="{\n"; cfg+="\tlogging_level = fatal\n"; cfg+="\toutput = cout\n"; cfg+="}\n"; if(!cfgfile.empty()) WriteFile(destFolder + "\\" + cfgfile, cfg); return 0; }
HRESULT CDBStepNC::SelectTable(CString tszSQL, StringTable &szColumnTable, StringTable &szDataTable) { USES_CONVERSION; HRESULT hr; //CTable<CDynamicAccessor> rs; CTable<CDynamicStringAccessor> rs; hr = rs.Open( m_session, "milling_cutter" ); hr = rs.MoveFirst( ); int j=0; while( SUCCEEDED( hr ) && hr != DB_S_ENDOFROWSET ) { for( size_t i = 1; i < rs.GetColumnCount( ); i++ ) { OutputDebugString(StrFormat( "Column %d [%S]= %s\n", i, rs.GetColumnName( i ), rs.GetString( i ) )); if(j==0) szColumnTable(0,i)=W2T(_bstr_t(rs.GetColumnName( i ))); szDataTable(j,i-1)=rs.GetString( i ); OutputDebugString(szDataTable(j,i)); } hr = rs.MoveNext( ); j++; } return hr; }
void CDatabaseConnection::connect() { mysql_close(_pMySQL); while(!mysql_real_connect(_pMySQL, _host.c_str(), _username.c_str(), _password.c_str(), _database.c_str(), _port, NULL, CLIENT_MULTI_STATEMENTS)) { Log(CLog::Error, StrFormat("Could not connect. ({0})", Error())); } }
bool EnablePrivilege(LPCWSTR privilegeStr, HANDLE hToken /* = NULL */) { TOKEN_PRIVILEGES tp; // token privileges LUID luid; bool bCloseToken = false; if(NULL == hToken) { if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { Log(StrFormat(L"Failed to open process to enable privilege %s", privilegeStr), false); return false; } bCloseToken = true; } if (!LookupPrivilegeValue(NULL, privilegeStr, &luid)) { if(bCloseToken) CloseHandle (hToken); _ASSERT(0); Log(StrFormat(L"Could not find privilege %s", privilegeStr), false); return false; } ZeroMemory (&tp, sizeof (tp)); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Adjust Token privileges if (!AdjustTokenPrivileges (hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { DWORD gle = GetLastError(); Log(StrFormat(L"Failed to adjust token for privilege %s", privilegeStr), gle); if(bCloseToken) CloseHandle (hToken); _ASSERT(0); return false; } if(bCloseToken) CloseHandle (hToken); return true; }
CQueryResult CDatabaseConnection::Query(const std::string& queryString) { // We don't want concurrent queries std::lock_guard<std::mutex> lock{_dbMutex}; while(mysql_query(_pMySQL, queryString.c_str()) != 0) { Log(CLog::Error, StrFormat("Error executing query {0}. ({1})", queryString, Error())); connect(); } MYSQL_RES* pRes = mysql_store_result(_pMySQL); if(pRes == NULL) { throw CDatabaseException(SRC_POS, StrFormat("Error getting result. ({0})", Error())); } return CQueryResult{pRes}; }
// line 1 - TOOL (start of tool definition) // line 2 - tool material (1-HSS, 2-CARBIDE, 3-COATED CAR, 4-CERAMIC, 5-BORZON, 10-UNKNOWN) // line 3 - tool comment // line 4 - tool name (geometry reference for backplot) // line 5 - tool manufacturer // line 6 - chuck designation // line 7 - tool_no, tool_type, rad_type, dia, crad, thds, tip_angle, // dia_off, len_off, feed, plunge, retract, rpm, coolant, n_flutes // line 8 - Drilling attributes (see tool_type in line 7 above) // line 8 - cycle, peck1, peck2, peck_clr, chip_brk, dwell, shldr_angle, root_dia (tap), bore_shift // line 8 - Milling attributes (see tool_type in line 7 above) // line 8 - cut_able, rgh_x, rgh_z, fin_x, fin_z, tip_dia, root_dia (thd mill), thd_angle // line 9 - pilot_dia, flute_len, oa_len, shldr_len, arbor_dia, hldr_dia, hldr_len, spindle_ccw, sfm, fpt, metric HRESULT CDBStepNC::LoadMasterCAMTool(CString filename) { CString contents = ReadAFile(filename); if(contents.GetLength()< 1) return E_INVALIDARG; CStringVector lines = CStringVector::Tokenize(contents, "\n"); CStringVector columns; columns.push_back("toolid"); columns.push_back("name"); columns.push_back("tooltypeid"); columns.push_back("materialid"); columns.push_back("number_of_teeth"); columns.push_back("hand_of_cut"); columns.push_back("coolant_through_tool"); columns.push_back("cutting_edge_length"); columns.push_back("flute_length"); columns.push_back("overall_length"); columns.push_back("shoulder_length"); columns.push_back("tip_diameter"); columns.push_back("tool_tip_half_angle"); columns.push_back("sfm"); columns.push_back("fpt"); columns.push_back("metric"); CStringVector values; values.resize(16); for(int i=40, j=1; i< lines.size(); i+=10, j++) { CStringVector items1 = CStringVector::Tokenize(lines[i+1]," "); CStringVector items2 = CStringVector::Tokenize(lines[i+2]," "); CStringVector items3 = CStringVector::Tokenize(lines[i+3]," "); CStringVector items7 = CStringVector::Tokenize(lines[i+7]," "); CStringVector items8 = CStringVector::Tokenize(lines[i+8]," "); CStringVector items9 = CStringVector::Tokenize(lines[i+9]," "); values[0] =StrFormat("%d", j); // toolid values[1]=lines[i+3].Mid(lines[i+3].Find("-")+1).Trim(); // name values[2]=items7[3].Trim(); // tooltypeid values[3]=items2[2].Trim(); // materialid values[4]= items7[16].Trim(); // number_of_teeth values[5]= (items9[9] ==1) ? "LEFT" : "RIGHT"; // hand_of_cut values[6]= items7[15]; // coolant_through_tool values[7]= items9[3]; // cutting_edge_length values[8]= items9[3]; // flute_length values[9]= items7[10]; // overall_length values[10]= items9[5]; // shoulder_length values[11]= items7[5]; // tip_diameter values[12]= items7[8]; // tool_tip_half_angle values[13]= items9[10]; // sfm values[14]= items9[11]; // fpt values[15]= items9[12].Trim(); // metric InsertRow("milling_cutter", columns, values); } return S_OK; }
std::string GamemodeTag(EGamemode gamemode) { switch (gamemode) { case EGamemode::Osu: return "osu"; case EGamemode::Taiko: return "taiko"; case EGamemode::Catch: return "catch_the_beat"; case EGamemode::Mania: return "osu_mania"; default: throw Exception{SRC_POS, StrFormat("Unknown gamemode requested. ({0})", gamemode)}; } }
std::string GamemodeName(EGamemode gamemode) { switch (gamemode) { case EGamemode::Osu: return "osu!"; case EGamemode::Taiko: return "osu!taiko"; case EGamemode::Catch: return "osu!catch"; case EGamemode::Mania: return "osu!mania"; default: throw Exception{SRC_POS, StrFormat("Unknown gamemode requested. ({0})", gamemode)}; } }
std::string GamemodeSuffix(EGamemode gamemode) { switch (gamemode) { case EGamemode::Osu: return ""; case EGamemode::Taiko: return "_taiko"; case EGamemode::Catch: return "_fruits"; case EGamemode::Mania: return "_mania"; default: throw Exception{SRC_POS, StrFormat("Unknown gamemode requested. ({0})", gamemode)}; } }
void CDatabaseConnection::NonQuery(const std::string& queryString) { // We don't want concurrent queries std::lock_guard<std::mutex> lock{_dbMutex}; while(mysql_query(_pMySQL, queryString.c_str()) != 0) { Log(CLog::Error, StrFormat("Error executing query {0}. ({1})", queryString, Error())); connect(); } s32 status; do { /* did current statement return data? */ MYSQL_RES* pRes = mysql_store_result(_pMySQL); if(pRes != NULL) { mysql_free_result(pRes); } else /* no result set or error */ { if(mysql_field_count(_pMySQL) == 0) { } else /* some error occurred */ { throw CDatabaseException(SRC_POS, StrFormat("Error getting result. ({0})", Error())); } } /* more results? -1 = no, >0 = error, 0 = yes (keep looping) */ status = mysql_next_result(_pMySQL); if(status > 0) { throw CDatabaseException(SRC_POS, StrFormat("Error executing query {0}. ({1})", queryString, Error())); } } while(status == 0); }
EGamemode ToGamemode(std::string modeString) { modeString = ToLower(modeString); if (modeString == "osu" || modeString == "osu!" || modeString == "standard") return EGamemode::Osu; else if (modeString == "taiko" || modeString == "osu!taiko") return EGamemode::Taiko; else if (modeString == "catch" || modeString == "osu!catch" || modeString == "fruits" || modeString == "catchthebeat" || modeString == "catch the beat") return EGamemode::Catch; else if (modeString == "mania" || modeString == "osu!mania") return EGamemode::Mania; else throw Exception{SRC_POS, StrFormat("Invalid mode '{0}'", modeString)}; }
CString GetSystemErrorMessage(DWORD lastErrorVal) { CString osErr = _T("Unknown error value. "); const int errSize = 8192; HMODULE hMod = NULL; DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; DWORD len = FormatMessage(flags, hMod, lastErrorVal, 0, osErr.GetBuffer(errSize), errSize - 50, NULL); osErr.ReleaseBuffer(); osErr.Replace(L"\r", L""); osErr.Replace(L"\n", L""); osErr += StrFormat(L" [Err=0x%0X, %u]", lastErrorVal, lastErrorVal); return osErr; }
int XLibraDIGI_SM::ProgrammingTovar(XLibraTovar tovar) { long nomen_num = tovar.nomen_num; //- // ((XEithernetConnection *)connection_descriptor)->prefix * 10000; long nomen_num_int = nomen_num; if (tovar.art_num > 9999) { sprintf(result.text, "Для %d код артиулу %d перевищує 9999", tovar.nomen_num, tovar.art_num); SaveToLog(result.text); result.critical = 0; return LIBRA_ERROR_PARAM; } ++tovar_pos; BYTE buf[1024]; int len(0); sprintf(buf, "%08d", tovar.art_num); memcpy(_recPLU.nPLU, buf, 8); len+=8; //BYTE nSize[2]; // HEX len+=2; memcpy(_recPLU.nStatus1, "5400", 4); len+=4; memcpy(_recPLU.nStatus2, "0D2601", 6); len+=6; long price = Around_0(tovar.price * 100.0); sprintf(buf, "%08d", price); memcpy(_recPLU.nPrice100, buf, 8); len+=8; // 4 Ціна в копійках memcpy(_recPLU.nFet1, "11", 2); len+=2; // HEX № формату 1-ї етикетки 11 memcpy(_recPLU.nFbCode, "04", 2); len+=2; // HEX № формату штрихкоду 09 sprintf(buf, "%02d%06d000000", ((XEithernetConnection *)connection_descriptor)->prefix, tovar.nomen_num); memcpy(_recPLU.nBCode, buf, 14); len+=14; // BCD Дані штрихкоду 22|28 + IntToBCD(nomen_No, 2) + '00000000' sprintf(buf, "%04d", tovar.termin); memcpy(_recPLU.nTerminDSell, buf, 4); len+=4; // BCD 0+Строк продажу в днях memcpy(_recPLU.nMsgNum, "01", 2); len+=2; // BCD Номер спец. повідомлення 01 memcpy(_recPLU.nIngradientNum, "01", 2); len+=2; // BCD Номер інградієнту 01 StrFormat(_recPLU.nName, tovar.name); int len_name = strlen(_recPLU.nName); len+=len_name + 4; sprintf(buf, "%04X", (int)(len)/2); memcpy(_recPLU.nSize, buf, 4); FILE* fp = fopen(tovar_name, "ab"); fwrite((char*)&_recPLU, len, 1, fp); fclose(fp); return 0; }
CString StrFormat(LPCTSTR pFormat, ...) //returns a formatted CString. Inspired by .NET's String.Format { CString result; DWORD size = max(4096, (DWORD)_tcslen(pFormat) + 4096); _ASSERT(NULL == wcsstr(pFormat, L"{0}")); //StrFormat2 should have been used?? GLOK try { while(true) { va_list pArg; va_start(pArg, pFormat); int res = _vsntprintf_s(result.GetBuffer(size), size, _TRUNCATE, pFormat, pArg); va_end(pArg); if(res >= 0) { result.ReleaseBuffer(); return result; } else { result.ReleaseBuffer(1); size += 8192; if(size > (12 * 1024 * 1024)) { _ASSERT(0); Log(StrFormat(L"STRING TOO LONG: %s", pFormat), true); CString s = L"<error - string too long -- "; //GLOK s += pFormat; s += L">"; //GLOK return s; } } } } catch(...) { _ASSERT(0); CString res = L"<string format exception: ["; //GLOK if(NULL != pFormat) res += pFormat; else res += L"(null)"; //GLOK res += L"]>"; //GLOK res.Replace(L'%', L'{'); //so no further formatting is attempted GLOK return res; } }
void SocketBackEnd::server(boost::asio::io_service& io_service, short port) { try { _pAcceptor = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), port)) ; _pAcceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); StartAsyncAccept(); // Thread will stop here... } catch(...) { std::cout << StrFormat("Fatal Error in SocketBackEnd::server\n"); } }
void Duplicate(HANDLE& h, LPCSTR file, int line) { HANDLE hDupe = NULL; if(DuplicateTokenEx(h, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDupe)) { CloseHandle(h); h = hDupe; hDupe = NULL; } else { DWORD gle = GetLastError(); _ASSERT(0); Log(StrFormat(L"Error duplicating a user token (%S, %d)", file, line), GetLastError()); } }
CDatabaseConnection::CDatabaseConnection( std::string host, s16 port, std::string username, std::string password, std::string database) : _host{std::move(host)}, _port{port}, _username{std::move(username)}, _password{std::move(password)}, _database{std::move(database)} { _pMySQL = new MYSQL; if(!mysql_init(_pMySQL)) { // Clean up in case of error delete _pMySQL; throw CDatabaseException(SRC_POS, StrFormat("MySQL struct could not be initialized. ({0})", Error())); } connect(); _pActive = CActive::Create(); }
void CException::Print() { std::cerr << StrFormat("Exception in: {0}:{1} - {2}\n", m_File, m_Line, m_Description); }
void SocketBackEnd::session(socket_ptr sock) { try { _set_se_translator( trans_func ); // correct thread? #if 0 if(_1stshdr.size()>0) boost::asio::write(*sock, boost::asio::buffer(_1stshdr.c_str(), _1stshdr.size())); #endif // FIXME need mutex - cant add while we are consuming _nshdrs=_allshdrsofar.size(); for(size_t i=0; i< _allshdrsofar.size(); i++) { boost::asio::write(*sock, boost::asio::buffer(_allshdrsofar[i].c_str(), _allshdrsofar[i].size())); Timing::Sleep(50); } aHeartbeatCnt=aHeartbeatFreq; for (nCount++;bRunning;) { aHeartbeatCnt-=100; // heartbeat countdown boost::this_thread::sleep(boost::posix_time::milliseconds(100)); // sleeping 100 millisecond! boost::system::error_code ec; boost::system::error_code error; std::string tmp; #if 0 if( aHeartbeatCnt < 0) { aHeartbeatCnt=aHeartbeatFreq; std::string mPong= StrFormat( "* PONG %d\n", aHeartbeatFreq); boost::asio::write(*sock, boost::asio::buffer(mPong.c_str(), mPong.size())); } #endif int n = ReadLine(sock, tmp); // n>=0 data... if (strncmp(tmp.c_str(), "* PING", 6) == 0) { std::string mPong= StrFormat( "* PONG %d\n", aHeartbeatFreq); boost::asio::write(*sock, boost::asio::buffer(mPong.c_str(), mPong.size())); Timing::Sleep(50); } else { std::string mPong= StrFormat( "* PONG %d\n", aHeartbeatFreq); boost::asio::write(*sock, boost::asio::buffer(mPong.c_str(), mPong.size())); Timing::Sleep(50); } std::cout<< "Received: " << tmp << std::endl; while(_nshdrs<_allshdrsofar.size()) { _shdr=_allshdrsofar[_nshdrs]; _nshdrs++; if(_shdr.size() < 1) continue; aHeartbeatCnt=aHeartbeatFreq; // See what's going out std::cout << _shdr << std::endl; boost::asio::write(*sock, boost::asio::buffer(_shdr.c_str(), _shdr.size())); Timing::Sleep(50); if(ec) throw boost::system::system_error(ec); // if (ec == boost::asio::error::eof) throw boost::system::system_error(ec); // } } } catch (std::exception& e) { std::cerr << "Exception in thread: " << e.what() << "\n"; } catch (...) { std::cerr << "Exception in thread\n"; } nCount--; }
static void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp ) { OutputDebugString( StrFormat("Shdr Echo Adapter trans_func - Code = 0x%x\n", pExp->ExceptionRecord->ExceptionCode).c_str() ); throw std::exception(); }
bool GetUserHandle(Settings& settings, BOOL& bLoadedProfile, PROFILEINFO& profile, HANDLE hCmdPipe) { DWORD gle = 0; if(settings.bUseSystemAccount) { if(BAD_HANDLE(settings.hUser)) //might already have hUser from a previous call { EnablePrivilege(SE_DEBUG_NAME); //helps with OpenProcess, required for GetLocalSystemProcessToken settings.hUser = GetLocalSystemProcessToken(); if(BAD_HANDLE(settings.hUser)) { Log(L"Not able to get Local System token", true); return false; } else Log(L"Got Local System handle", false); Duplicate(settings.hUser, __FILE__, __LINE__); } return true; } else { //not Local System, so either as specified user, or as current user if(FALSE == settings.user.IsEmpty()) { CString user, domain; GetUserDomain(settings.user, user, domain); BOOL bLoggedIn = LogonUser(user, domain.IsEmpty() ? NULL : domain, settings.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_WINNT50, &settings.hUser); gle = GetLastError(); #ifdef _DEBUG Log(L"DEBUG: LogonUser", gle); #endif if((FALSE == bLoggedIn) || BAD_HANDLE(settings.hUser)) { Log(StrFormat(L"Error logging in as %s", settings.user), gle); return false; } else Duplicate(settings.hUser, __FILE__, __LINE__); //gives max rights if(!BAD_HANDLE(settings.hUser) && (false == settings.bDontLoadProfile)) { EnablePrivilege(SE_RESTORE_NAME); EnablePrivilege(SE_BACKUP_NAME); bLoadedProfile = LoadUserProfile(settings.hUser, &profile); #ifdef _DEBUG gle = GetLastError(); Log(L"DEBUG: LoadUserProfile", gle); #endif } return true; } else { //run as current user if(NULL != hCmdPipe) { BOOL b = ImpersonateNamedPipeClient(hCmdPipe); DWORD gle = GetLastError(); if(FALSE == b) Log(L"Failed to impersonate client user", gle); else Log(L"Impersonated caller", false); } HANDLE hThread = GetCurrentThread(); BOOL bDupe = DuplicateHandle(GetCurrentProcess(), hThread, GetCurrentProcess(), &hThread, 0, TRUE, DUPLICATE_SAME_ACCESS); DWORD gle = GetLastError(); BOOL bOpen = OpenThreadToken(hThread, TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &settings.hUser); gle = GetLastError(); if(1008 == gle) //no thread token { bOpen = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &settings.hUser); gle = GetLastError(); } if(FALSE == bOpen) Log(L"Failed to open current user token", GetLastError()); Duplicate(settings.hUser, __FILE__, __LINE__); //gives max rights RevertToSelf(); return !BAD_HANDLE(settings.hUser); } } }
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; }
void CLoggedException::Log() { ::Log(CLog::EType::Exception, StrFormat("{0}:{1} - {2}", m_File, m_Line, m_Description)); }