UINT CPackage::executePostCmd( UINT uCommandTimeOut) { CLog *pLog = getOcsLogger(); CExecCommand cmProcess; CString csBuffer; HANDLE hToken; TOKEN_PRIVILEGES tkp; // check if there is post command to execute if (m_csPostCmd.IsEmpty()) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => No post execution command provided for package <%s>"), m_csID); return TRUE; } // Check if post command is REBOOT if (m_csPostCmd == OCS_DOWNLOAD_POST_CMD_REBOOT) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing post execution command <%s> for package <%s>"), m_csPostCmd, m_csID); // Request ability to restart computer if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Reboot privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } if (!LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Reboot privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Reboot privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } // Initiate a planned restart to perform application installation. if (!InitiateSystemShutdownEx( NULL, _T( "OCS Inventory NG must REBOOT your system after package setup"), uCommandTimeOut, TRUE, TRUE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to initiate System Reboot after package <%s> execution: %s"), m_csID, LookupError( GetLastError())); return FALSE; } return TRUE; } // Check if post command is SHUTDOWN if (m_csPostCmd == OCS_DOWNLOAD_POST_CMD_SHUTDOWN) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing post execution command <%s> for package <%s>"), m_csPostCmd, m_csID); // Request ability to shutdown computer if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Shutdown privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } if (!LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Shutdown privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to request Shutdown privilege for package <%s>: %s"), m_csID, LookupError( GetLastError())); return FALSE; } // Initiate a planned shutdown to perform application installation. if (!InitiateSystemShutdownEx( NULL, _T( "OCS Inventory NG must SHUTDOWN your system after package setup"), uCommandTimeOut, TRUE, FALSE, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unable to initiate System Shutdown after package <%s> execution: %s"), m_csID, LookupError( GetLastError())); return FALSE; } return TRUE; } // Execute default post command pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing post execution command <%s> for package <%s>"), m_csPostCmd, m_csID); // Set command time out in milliseconds cmProcess.setTimeout( uCommandTimeOut * 60 * 1000); // Execute command and wait only for main process to terminate switch (cmProcess.execWait( m_csPostCmd, m_csPath)) { case EXEC_ERROR_START_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to execute post execution command <%s> for package <%s> (%s)"), m_csPostCmd, m_csID, cmProcess.getOutput()); setDone( ERR_EXECUTE); return FALSE; case EXEC_ERROR_WAIT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to get post execution command <%s> result code for package <%s> (%s)"), m_csPostCmd, m_csID, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_NO_EXIT_CODE; return FALSE; case EXEC_ERROR_TIMEOUT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Post execution command <%s> execution reached timeout (%s)"), m_csPostCmd, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_TIMEOUT; return FALSE; default: pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> post execution command successfully executed. Command exit code is <%d>"), m_csID, cmProcess.getExitValue()); if (cmProcess.getExitValue() != 0) // Command result code is not a success csBuffer.Format( _T( "%s%d"), ERR_EXIT_CODE, cmProcess.getExitValue()); else csBuffer = CODE_SUCCESS; break; } return TRUE; }
UINT CPackage::execute( UINT uCommandTimeOut) { CLog *pLog = getOcsLogger(); CExecCommand cmProcess; CString csBuffer; UINT uTry; // Check signature before executing package if (!checkSignature()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed verifying signature for Package <%s>"), m_csID); setDone( ERR_BAD_DIGEST); return FALSE; } // Check if package not crashing all time if (!getExecTry( &uTry)) // Assuming first execution try uTry = 0; uTry++; if (uTry > MAX_ERROR_COUNT) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Max try count (%u) reached while executing Package <%s>"), uTry, m_csID); setDone( ERR_EXECUTE_TOO_MANY_TRY); return FALSE; } else setExecTry( uTry); if (m_csAction == OCS_DOWNLOAD_ACTION_LAUNCH) { // We need to wait for all threads/processes started // First, extrac build.zip to tmp folder if (!directoryCreate( m_csPath) || !unZip()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to unzip package <%s> to folder <%s>"), m_csID, m_csPath); setDone( ERR_UNZIP); return FALSE; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Launching command <%s> for package <%s> on <%s>"), m_csCommand, m_csID, CTime::GetCurrentTime().Format( _T( "%#c"))); if (m_csCommand.IsEmpty()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => No command provided for <%s> action of package <%s>"), OCS_DOWNLOAD_ACTION_LAUNCH, m_csID); setDone( ERR_BAD_PARAM); return FALSE; } // Set command time out in milliseconds cmProcess.setTimeout( uCommandTimeOut * 60 * 1000); // Execute command and wait for all childs to terminate switch (cmProcess.execWaitForAllChilds( m_csCommand, m_csPath)) { case EXEC_ERROR_START_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to launch command <%s> for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); setDone( ERR_EXECUTE); return FALSE; case EXEC_ERROR_WAIT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to get command <%s> result code for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_NO_EXIT_CODE; break; case EXEC_ERROR_TIMEOUT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Command <%s> execution reached timeout on <%s> (%s)"), m_csCommand, CTime::GetCurrentTime().Format( _T( "%#c")), cmProcess.getOutput()); csBuffer = ERR_EXECUTE_TIMEOUT; break; default: isExecSuccessful( cmProcess.getExitValue(), csBuffer); pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> successfully launched. Command exit code is <%d>. Package return code is <%s>"), m_csID, cmProcess.getExitValue(), csBuffer); break; } setDone( csBuffer); return TRUE; } if (m_csAction == OCS_DOWNLOAD_ACTION_EXECUTE) { // We only need to wait for cmmand result // First, extrac build.zip to tmp folder if (!directoryCreate( m_csPath) || !unZip()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to unzip package <%s> to folder <%s>"), m_csID, m_csPath); setDone( ERR_UNZIP); return FALSE; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing command <%s> for package <%s> on <%s>"), m_csCommand, m_csID, CTime::GetCurrentTime().Format( _T( "%#c"))); if (m_csCommand.IsEmpty()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => No command provided for <%s> action of package <%s>"), OCS_DOWNLOAD_ACTION_EXECUTE, m_csID); setDone( ERR_BAD_PARAM); return FALSE; } // Set command time out in milliseconds cmProcess.setTimeout( uCommandTimeOut * 60 * 1000); // Execute command and wait only for main process to terminate switch (cmProcess.execWait( m_csCommand, m_csPath)) { case EXEC_ERROR_START_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to execute command <%s> for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); setDone( ERR_EXECUTE); return FALSE; case EXEC_ERROR_WAIT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to get command <%s> result code for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_NO_EXIT_CODE; break; case EXEC_ERROR_TIMEOUT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Command <%s> execution reached timeout on <%s> (%s)"), m_csCommand, CTime::GetCurrentTime().Format( _T( "%#c")), cmProcess.getOutput()); csBuffer = ERR_EXECUTE_TIMEOUT; break; default: isExecSuccessful( cmProcess.getExitValue(), csBuffer); pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> successfully executed. Command exit code is <%d>. Package return code is <%s>"), m_csID, cmProcess.getExitValue(), csBuffer); } setDone( csBuffer, GetUnicodeFromAnsi( cmProcess.getOutput())); return TRUE; } if (m_csAction == OCS_DOWNLOAD_ACTION_STORE) { // We just want to unzip data to specified folder pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Unzipping data to folder <%s> for package <%s> on <%s>"), m_csPath, m_csID, CTime::GetCurrentTime().Format( _T( "%#c"))); if (m_csPath.IsEmpty()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => No path provided for <%s> action of package <%s>"), OCS_DOWNLOAD_ACTION_STORE, m_csID); setDone( ERR_BAD_PARAM); return FALSE; } if (!directoryCreate( m_csPath) || !unZip()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to unzip package <%s> to folder <%s>"), m_csID, m_csPath); setDone( ERR_UNZIP); return FALSE; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> successfully stored to folder <%s>"), m_csID, m_csPath); setDone( CODE_SUCCESS); return TRUE; } // Unknown action pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unknown action <%s> for package <%s>"), m_csAction, m_csID); setDone( ERR_BAD_PARAM); return FALSE; }