Confdump Agent
1.4.0
|
00001 /* 00002 * Confdump-Agent - Dump static and runtime system configuration 00003 * Copyright (C) 2009-2012 Straton IT, SAS 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 3 as 00007 * published by the Free Software Foundation. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include <windows.h> 00019 #include <initguid.h> 00020 #include <ole2.h> 00021 #include <mstask.h> 00022 #include <msterr.h> 00023 00024 #include "QVariant" 00025 00026 #include "boost/shared_ptr.hpp" 00027 #include "boost/shared_array.hpp" 00028 #include "boost/foreach.hpp" 00029 #include "boost/function.hpp" 00030 #include "Confdump/System/WMI/errors.hpp" 00031 #include "Confdump/System/Win32/ScheduledTask.hpp" 00032 00033 using boost::shared_ptr; 00034 using boost::shared_array; 00035 using Confdump::System::Wmi::ComContext; 00036 using Confdump::System::Wmi::throwOnComError; 00037 using Confdump::System::Wmi::guardComObject; 00038 00039 namespace Confdump 00040 { 00041 00042 namespace System 00043 { 00044 00045 namespace Win32 00046 { 00047 00048 namespace 00049 { 00050 00051 void freeFetchedTasks1( LPWSTR *tasks ) 00052 { 00053 if ( tasks ) 00054 { 00055 CoTaskMemFree( tasks[0] ); 00056 CoTaskMemFree( tasks ); 00057 } 00058 } 00059 00060 shared_ptr<ITaskScheduler> getTaskScheduler() 00061 { 00062 ITaskScheduler *rawScheduler = 0; 00063 HRESULT hr = CoCreateInstance( 00064 CLSID_CTaskScheduler, 00065 0, 00066 CLSCTX_INPROC_SERVER, 00067 IID_ITaskScheduler, 00068 reinterpret_cast<void**>( &rawScheduler ) ); 00069 throwOnComError( hr, "contact the Windows task scheduler" ); 00070 shared_ptr<ITaskScheduler> scheduler = guardComObject( rawScheduler ); 00071 00072 return scheduler; 00073 } 00074 00075 QStringList allTaskNames( shared_ptr<ITaskScheduler> scheduler ) 00076 { 00077 QStringList taskNames; 00078 00079 IEnumWorkItems *rawEnumWI; 00080 HRESULT hr = scheduler->Enum( &rawEnumWI ); 00081 throwOnComError( hr, "enumerate the Windows scheduled tasks" ); 00082 shared_ptr<IEnumWorkItems> enumWI = guardComObject( rawEnumWI ); 00083 00084 for ( ;; ) 00085 { 00086 LPWSTR *rawNames = 0; 00087 hr = enumWI->Next( 1, &rawNames, 0 ); 00088 throwOnComError( hr, "enumerate the next Windows scheduled task" ); 00089 shared_array<LPWSTR> names( rawNames, freeFetchedTasks1 ); 00090 if ( hr != S_OK ) 00091 break; 00092 taskNames << QString::fromWCharArray( names[0] ); 00093 }; 00094 00095 return taskNames; 00096 } 00097 00098 typedef boost::function< HRESULT( ITask*, LPWSTR *) > TaskStringGetter; 00099 00100 QString getStringProperty( shared_ptr<ITask> task, TaskStringGetter getter ) 00101 { 00102 LPWSTR rawString = 0; 00103 HRESULT hr = getter( task.get(), &rawString ); 00104 // Scheduled tasks easily become corrupted, do not throw on error 00105 if ( SUCCEEDED( hr ) ) 00106 { 00107 shared_array<wchar_t> str( rawString, CoTaskMemFree ); 00108 return QString::fromWCharArray( str.get() ); 00109 } 00110 else 00111 { 00112 return QString(); 00113 } 00114 } 00115 00116 QString getStatusString( shared_ptr<ITask> task ) 00117 { 00118 HRESULT status = 0; 00119 HRESULT hr = task->GetStatus( &status ); 00120 throwOnComError( hr, "get the status of a Windows Scheduled Task" ); 00121 00122 // Comments from http://msdn.microsoft.com/en-us/library/windows/desktop/aa381263%28v=VS.85%29.aspx 00123 switch ( status ) 00124 { 00125 // The work item is ready to run at its next scheduled time. 00126 case SCHED_S_TASK_READY: return "READY"; 00127 // The work item is currently running. 00128 case SCHED_S_TASK_RUNNING: return "RUNNING"; 00129 // One or more of the properties that are needed to run this task on a schedule have not been set. 00130 case SCHED_S_TASK_NOT_SCHEDULED: return "NOT_SCHEDULED"; 00131 // The task has not been run. This value is returned whenever the task has not been run, 00132 // even if the task is ready to be run at the next scheduled time or the task is a recurring task. 00133 case SCHED_S_TASK_HAS_NOT_RUN: return "HAS_NOT_RUN"; 00134 // The task will not run at the scheduled times because it has been disabled. 00135 case SCHED_S_TASK_DISABLED: return "DISABLED"; 00136 // There are no more runs scheduled for this task. 00137 case SCHED_S_TASK_NO_MORE_RUNS: return "NO_MORE_RUNS"; 00138 // Either the task has no triggers or the existing triggers are disabled or not set. 00139 case SCHED_S_TASK_NO_VALID_TRIGGERS: return "NO_VALID_TRIGGERS"; 00140 default: return QString(); 00141 } 00142 } 00143 00144 } // ns 00145 00146 00147 Result ScheduledTask::allSystemInstances( Wmi::ComContext::Guard com ) 00148 { 00149 Result allTasks; 00150 00151 shared_ptr<ITaskScheduler> scheduler = getTaskScheduler(); 00152 00153 QStringList allNames = allTaskNames( scheduler ); 00154 BOOST_FOREACH( QString name, allNames ) 00155 { 00156 Result::Row task( new ScheduledTask( com, name, scheduler ) ); 00157 allTasks.push_back( task ); 00158 } 00159 00160 return allTasks; 00161 } 00162 00163 ScheduledTask::ScheduledTask( Wmi::ComContext::Guard com, QString name, boost::shared_ptr<ITaskScheduler> scheduler ) 00164 { 00165 if ( !scheduler ) 00166 scheduler = getTaskScheduler(); 00167 00168 ITask *rawTask; 00169 HRESULT hr = scheduler->Activate( 00170 name.toStdWString().c_str(), 00171 IID_ITask, reinterpret_cast<IUnknown**>( &rawTask ) ); 00172 throwOnComError( hr, "acquire a task from the Windows Scheduler" ); 00173 shared_ptr<ITask> task = guardComObject( rawTask ); 00174 00175 setProperty( "name", name ); 00176 setProperty( "applicationName", getStringProperty( task, &ITask::GetApplicationName ) ); 00177 setProperty( "parameters", getStringProperty( task, &ITask::GetParameters ) ); 00178 setProperty( "workingDirectory", getStringProperty( task, &ITask::GetWorkingDirectory ) ); 00179 setProperty( "accountInformation", getStringProperty( task, &ITask::GetAccountInformation ) ); 00180 setProperty( "comment", getStringProperty( task, &ITask::GetComment ) ); 00181 setProperty( "creator", getStringProperty( task, &ITask::GetCreator ) ); 00182 setProperty( "status", getStatusString( task ) ); 00183 } 00184 00185 ScheduledTask::~ScheduledTask() 00186 { 00187 } 00188 00189 } 00190 } 00191 }