Confdump Agent  1.4.0
ScheduledTask.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends