///////////////////////////////////////////////////////////////////////
//
void SaveTask( ITask *pTask )
{
IPersistFile *pPersistFile;
if( NULL != pTask )
{
HRESULT hr;
if( SUCCEEDED( pTask->QueryInterface( IID_IPersistFile, (void **) &pPersistFile ) ) )
{
hr = pPersistFile->Save( NULL, TRUE );
// Release the IPersistFile interface.
pPersistFile->Release();
}
}
}
///////////////////////////////////////////////////////////////////////
//
XS( XS_Win32__Scheduler_TIE_HASH )
{
dXSARGS;
EXTENSION_VARS;
HV *phvObject = NULL;
SV *psvSelf = NULL;
SV *psvResult = NULL;
// Maybe here we should allow you to connect to a remote machine??
if( ( 1 > items ) || ( 2 < items ) )
{
croak( "Usage: " EXTENSION "::TIEHASH( $Self [, $Machine ] )\n" );
}
psvSelf = ST( 0 );
phvObject = newHV();
if( NULL != phvObject )
{
ITaskScheduler *pITS = NULL;
HRESULT hr = CoCreateInstance( CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(void **) &pITS );
if( SUCCEEDED( hr ) )
{
if( 2 == items )
{
LPTSTR pszMachine = SvPV( ST( 1 ), na );
if( 0 != _tcscmp( pszMachine, TEXT( "" ) ) )
{
CUString szuMachine( pszMachine );
hr = pITS->SetTargetComputer( szuMachine );
}
}
if( SUCCEEDED( hr ) )
{
HASH_STORE_IV( phvObject, KEYWORD_SCHEDULER_INTERFACE, pITS );
psvResult = sv_bless( sv_2mortal( newRV_noinc( (SV*) phvObject ) ),
gv_stashpv( EXTENSION , TRUE ) );
}
}
}
if( NULL != psvResult )
{
PUSH_NOREF( psvResult );
}
EXTENSION_RETURN;
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_FETCH)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
ITaskScheduler *pITS = NULL;
HRESULT hr = ERROR_SUCCESS;
DWORD dwTotal = 0;
BOOL fResult = FALSE;
LPTSTR pszName = NULL;
SV *pSvResult = NULL;
if (items != 2)
{
croak("Usage: " EXTENSION "::TIEFETCH( $Self, $Key )\n");
}
// FETCH
phvSelf = (HV*) SvRV( ST( 0 ) );
pszName = SvPV( ST( 1 ), na );
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
CUString szuBuffer( pszName );
ITask *pTask = NULL;
if( SUCCEEDED( pITS->Activate( szuBuffer, IID_ITask, (IUnknown**) &pTask ) ) )
{
// Here we should create a new object and make it magic...
pSvResult = TieTask( PERL_OBJECT_ARGS pTask );
if( NULL != pSvResult )
{
// ST(0) = sv_newmortal();
// sv_setsv( ST(0), svResult);
PUSH_NOREF( pSvResult );
}
/*
HV *pHv = newHV();
if( NULL != pHv )
{
WORD wBuffer;
WORD wBuffer2;
DWORD dwBuffer;
LPWSTR pszBuffer = NULL;
if( SUCCEEDED( pTask->GetAccountInformation( &pszBuffer ) ) )
{
szuBuffer = pszBuffer;
HASH_STORE_PV( pHv, KEYWORD_JOB_ACCOUNT, (LPTSTR) szuBuffer );
CoTaskMemFree ( pszBuffer );
}
if( SUCCEEDED( pTask->GetApplicationName( &pszBuffer ) ) )
{
szuBuffer = pszBuffer;
HASH_STORE_PV( pHv, KEYWORD_JOB_APPLICATION, (LPTSTR) szuBuffer );
CoTaskMemFree ( pszBuffer );
}
if( SUCCEEDED( pTask->GetComment( &pszBuffer ) ) )
{
szuBuffer = pszBuffer;
HASH_STORE_PV( pHv, KEYWORD_JOB_COMMENT, (LPTSTR) szuBuffer );
CoTaskMemFree ( pszBuffer );
}
if( SUCCEEDED( pTask->GetCreator( &pszBuffer ) ) )
{
szuBuffer = pszBuffer;
HASH_STORE_PV( pHv, KEYWORD_JOB_CREATOR, (LPTSTR) szuBuffer );
CoTaskMemFree ( pszBuffer );
}
if( SUCCEEDED( pTask->GetParameters( &pszBuffer ) ) )
{
szuBuffer = pszBuffer;
HASH_STORE_PV( pHv, KEYWORD_JOB_PARAMETERS, (LPTSTR) szuBuffer );
CoTaskMemFree ( pszBuffer );
}
if( SUCCEEDED( pTask->GetWorkingDirectory( &pszBuffer ) ) )
{
szuBuffer = pszBuffer;
HASH_STORE_PV( pHv, KEYWORD_JOB_DIRECTORY, (LPTSTR) szuBuffer );
CoTaskMemFree ( pszBuffer );
}
if( SUCCEEDED( pTask->GetErrorRetryCount( &wBuffer ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_RETRY_COUNT, wBuffer );
}
if( SUCCEEDED( pTask->GetErrorRetryInterval( &wBuffer ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_RETRY_INTERVAL, wBuffer );
}
if( SUCCEEDED( pTask->GetExitCode( &dwBuffer ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_EXIT_CODE, dwBuffer );
}
if( SUCCEEDED( pTask->GetFlags( &dwBuffer ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_FLAGS, dwBuffer );
}
if( SUCCEEDED( pTask->GetIdleWait( &wBuffer, &wBuffer2 ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_IDLE_MINUTES, wBuffer );
HASH_STORE_IV( pHv, KEYWORD_JOB_DEADLINE_MINUTES, wBuffer2 );
}
if( SUCCEEDED( pTask->GetMaxRunTime( &dwBuffer ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_MAX_RUN_TIME, dwBuffer );
}
if( SUCCEEDED( pTask->GetPriority( &dwBuffer ) ) )
{
HASH_STORE_IV( pHv, KEYWORD_JOB_PRIORITY, dwBuffer );
}
PUSH_HV( pHv );
}
pTask->Release();
*/
}
}
EXTENSION_RETURN;
}
///////////////////////////////////////////////////////////////////////
//
XS( XS_Win32__Scheduler_TIE_STORE )
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
HV *pHvJob;
ITaskScheduler *pITS = NULL;
HRESULT hr = ERROR_SUCCESS;
DWORD dwTotal = 0;
BOOL fResult = FALSE;
LPTSTR pszName = NULL;
if( 3 != items )
{
croak( "Usage: " EXTENSION "::TIESTORE( $Self, $Key, \\%Job )\n" );
}
phvSelf = (HV*) SvRV( ST( 0 ) );
pszName = SvPV( ST( 1 ), na );
pHvJob = EXTRACT_HV( ST( 2 ) );
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( ( NULL != pITS ) && ( NULL != pHvJob ) )
{
CUString szuBuffer( pszName );
// IScheduledWorkItem *pWorkItem = NULL;
ITask *pTask = NULL;
BOOL fNewTask = FALSE;
// First check if the element already exists. If so then modify it
// otherwise create a new task
hr = pITS->Activate( szuBuffer, IID_ITask, (IUnknown**) &pTask );
if( FAILED( hr ) )
{
hr = pITS->NewWorkItem( szuBuffer, CLSID_CTask, IID_ITask, (IUnknown**) &pTask );
fNewTask = TRUE;
}
if( SUCCEEDED( hr ) )
{
CUString szuBuffer2;
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_ACCOUNT ) ) )
{
szuBuffer = HASH_GET_PV( pHvJob, KEYWORD_JOB_ACCOUNT );
szuBuffer2 = HASH_GET_PV( pHvJob, KEYWORD_JOB_PASSWORD );
hr = pTask->SetAccountInformation( szuBuffer, szuBuffer2 );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_COMMENT ) ) )
{
szuBuffer = HASH_GET_PV( pHvJob, KEYWORD_JOB_COMMENT );
hr = pTask->SetComment( szuBuffer );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_CREATOR ) ) )
{
szuBuffer = HASH_GET_PV( pHvJob, KEYWORD_JOB_CREATOR );
hr = pTask->SetCreator( szuBuffer );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_RETRY_COUNT ) ) )
{
WORD wRetryCount = (WORD) HASH_GET_IV( pHvJob, KEYWORD_JOB_RETRY_COUNT );
hr = pTask->SetErrorRetryCount( wRetryCount );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_RETRY_INTERVAL ) ) )
{
WORD wRetryInterval = (WORD) HASH_GET_IV( pHvJob, KEYWORD_JOB_RETRY_INTERVAL );
hr = pTask->SetErrorRetryInterval( wRetryInterval );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_FLAGS ) ) )
{
DWORD dwFlags = HASH_GET_IV( pHvJob, KEYWORD_JOB_FLAGS );
hr = pTask->SetFlags( dwFlags );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_CREATOR ) ) )
{
WORD wIdleMinutes = HASH_GET_IV( pHvJob, KEYWORD_JOB_IDLE_MINUTES );
WORD wDeadlineMinutes = HASH_GET_IV( pHvJob, KEYWORD_JOB_DEADLINE_MINUTES );
hr = pTask->SetIdleWait( wIdleMinutes, wDeadlineMinutes );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_DATA ) ) )
{
SV* pSv = HASH_GET_SV( pHvJob, KEYWORD_JOB_DATA );
PBYTE pData = (PBYTE) SvPV( pSv, na );
DWORD dwDataLength = SvLEN( pSv );
hr = pTask->SetWorkItemData( dwDataLength, (BYTE*) pData );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_APPLICATION ) ) )
{
szuBuffer = HASH_GET_PV( pHvJob, KEYWORD_JOB_APPLICATION );
hr = pTask->SetApplicationName( szuBuffer );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_DIRECTORY ) ) )
{
szuBuffer = HASH_GET_PV( pHvJob, KEYWORD_JOB_DIRECTORY );
hr = pTask->SetWorkingDirectory( szuBuffer );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_PRIORITY ) ) )
{
DWORD dwPriority = HASH_GET_IV( pHvJob, KEYWORD_JOB_PRIORITY );
hr = pTask->SetPriority( dwPriority );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_MAX_RUN_TIME ) ) )
{
DWORD dwMaxRunTime = HASH_GET_IV( pHvJob, KEYWORD_JOB_MAX_RUN_TIME );
hr = pTask->SetMaxRunTime( dwMaxRunTime );
}
if( SUCCEEDED( hr ) && ( HASH_KEY_EXISTS( pHvJob, KEYWORD_JOB_PARAMETERS ) ) )
{
szuBuffer = HASH_GET_PV( pHvJob, KEYWORD_JOB_PARAMETERS );
hr = pTask->SetParameters( szuBuffer );
}
if( SUCCEEDED( hr ) )
{
if( TRUE == fNewTask )
{
szuBuffer = pszName;
if( SUCCEEDED( pITS->AddWorkItem( szuBuffer, pTask ) ) )
{
fResult = TRUE;
}
}
else
{
fResult = TRUE;
}
}
SaveTask( pTask );
if( TRUE == fResult )
{
PUSH_IV( 1 );
}
pTask->Release();
}
}
EXTENSION_RETURN;
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_FIRSTKEY)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
ITaskScheduler *pITS = NULL;
HRESULT hr = ERROR_SUCCESS;
DWORD dwTotal = 0;
BOOL fResult = FALSE;
LPTSTR pszPreviousKey = NULL;
if( 1 != items )
{
croak( "Usage: " EXTENSION "::FIRSTKEY( $Self )\n" );
}
phvSelf = (HV*) SvRV( ST( 0 ) );
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
IEnumWorkItems *pEnum = NULL;
if( SUCCEEDED( pITS->Enum( &pEnum ) ) )
{
LPWSTR *pszwNames;
DWORD dwTasks = 0;
DWORD dwTasksToFetch = 1;
CUString szuName;
BOOL fFound = FALSE;
if( SUCCEEDED( pEnum->Next( dwTasksToFetch,
&pszwNames,
&dwTasks ) )
&& ( 0 != dwTasks ) )
{
DWORD dwCount;
szuName = pszwNames[ 0 ];
CoTaskMemFree( pszwNames[ 0 ] );
// if( 0 == ( dwCount = FindSubString( szuName, TEXT( ".job" ) ) ) )
{
dwCount = _tcslen( (LPTSTR) szuName );
}
PUSH_PNV( (LPTSTR) szuName, dwCount );
}
CoTaskMemFree( pszwNames );
pEnum->Release();
}
}
EXTENSION_RETURN;
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_NEXTKEY)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
ITaskScheduler *pITS = NULL;
HRESULT hr = ERROR_SUCCESS;
DWORD dwTotal = 0;
BOOL fResult = FALSE;
LPTSTR pszPreviousKey = NULL;
if( 2 != items )
{
croak( "Usage: " EXTENSION "::NEXTKEY( $Self, $PreviousKey )\n" );
}
pszPreviousKey = SvPV( ST( 1 ), na );
phvSelf = (HV*) SvRV( ST( 0 ) );
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
IEnumWorkItems *pEnum = NULL;
if( SUCCEEDED( pITS->Enum( &pEnum ) ) )
{
LPWSTR *pszwNames;
DWORD dwTasks = 0;
DWORD dwTasksToFetch = TOTAL_TASKS_TO_RETRIEVE;
CUString szuName;
BOOL fFound = FALSE;
while( SUCCEEDED( pEnum->Next( dwTasksToFetch,
&pszwNames,
&dwTasks ) )
&& ( 0 != dwTasks )
&& ( FALSE == fResult ) )
{
DWORD dwIndex = 0;
while( dwIndex < dwTasks )
{
szuName = pszwNames[ dwIndex ];
CoTaskMemFree( pszwNames[ dwIndex++ ] );
if( TRUE == fFound )
{
DWORD dwCount;
fResult = TRUE;
// if( 0 == ( dwCount = FindSubString( szuName, TEXT( ".job" ) ) ) )
{
dwCount = _tcslen( (LPTSTR) szuName );
}
PUSH_PNV( (LPTSTR) szuName, dwCount );
while( dwIndex < dwTasks )
{
CoTaskMemFree( pszwNames[ dwIndex++ ] );
}
break;
}
else if( 0 == _tcsicmp( szuName, pszPreviousKey ) )
{
fFound = TRUE;
}
}
CoTaskMemFree( pszwNames );
}
pEnum->Release();
}
}
EXTENSION_RETURN;
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_EXISTS)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
ITaskScheduler *pITS = NULL;
HRESULT hr = ERROR_SUCCESS;
LPTSTR pszKey = NULL;
DWORD dwTotal = 0;
BOOL fResult = FALSE;
if( 2 != items )
{
croak( "Usage: " EXTENSION "::EXISTS( $Self, $Key )\n" );
}
pszKey = SvPV( ST( 1 ), na);
phvSelf = (HV*) SvRV( ST( 0 ) );
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
CUString szuBuffer( pszKey );
ITask *pTask = NULL;
BOOL fNewTask = FALSE;
// First check if the element already exists. If so then modify it
// otherwise create a new task
if( SUCCEEDED( pITS->Activate( szuBuffer, IID_ITask, (IUnknown**) &pTask ) ) )
{
fResult = TRUE;
pTask->Release();
}
}
/*
IEnumWorkItems *pEnum = NULL;
if( SUCCEEDED( pITS->Enum( &pEnum ) ) )
{
LPWSTR *pszwNames;
DWORD dwTasks = 0;
DWORD dwTasksToFetch = TOTAL_TASKS_TO_RETRIEVE;
CUString szuName;
while( SUCCEEDED( pEnum->Next( dwTasksToFetch,
&pszwNames,
&dwTasks ) )
&& ( 0 != dwTasks )
&& ( FALSE == fResult ) )
{
DWORD dwIndex = 0;
while( dwIndex < dwTasks )
{
szuName = pszwNames[ dwIndex ];
CoTaskMemFree( pszwNames[ dwIndex++ ] );
if( ( FALSE == fResult ) && ( 0 == _tcsicmp( szuName, pszKey ) ) )
{
fResult = TRUE;
}
}
CoTaskMemFree( pszwNames );
}
pEnum->Release();
}
}
*/
EXTENSION_RETURN_BOOL( fResult );
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_CLEAR)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
ITaskScheduler *pITS = NULL;
HRESULT hr = ERROR_SUCCESS;
DWORD dwTotal = 0;
if( 1 != items )
{
croak( "Usage: " EXTENSION "::CLEAR( $Self )\n" );
}
#ifdef CLEAR_WORK_ITEMS
// This is VERY dangerous as it will clear out all of the
// registered work items. BE CAREFULL IF YOU USE THIS!!!
phvSelf = (HV*) SvRV( ST( 0 ) );
pITS = (ITaskScheduler *) HASH_GET_IV( hvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
IEnumWorkItems *pEnum = NULL;
if( SUCCEEDED( pITS->Enum( &pEnum ) )
{
LPWSTR *pszwNames;
DWORD dwTasks = 0;
DWORD dwTasksToFetch = TOTAL_TASKS_TO_RETRIEVE;
CUString szuName;
while( SUCCEEDED( pIEnum->Next( dwTasksToFetch,
&pszwNames,
&dwTasks ) )
&& ( 0 != dwTasks ) )
{
while( dwTasks )
{
szuName = pszwNames[ --dwTasks ];
CoTaskMemFree( pszwNames[ dwTasks ] );
dwTotal++;
hr = pITS->Delete( pszuName );
}
CoTaskMemFree( pszwNames );
}
pIEnum->Release();
}
}
#endif // CLEAR_WORK_ITEMS
EXTENSION_RETURN_BOOL( SUCCEEDED( hr ) );
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_DELETE)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
ITaskScheduler *pITS = NULL;
HRESULT hr;
CUString szuName;
if( 2 != items )
{
croak( "Usage: " EXTENSION "::DELETE( $Self, $Key )\n" );
}
// DELETE
phvSelf = (HV*) SvRV( ST( 0 ) );
szuName = SvPV( ST( 1 ), na);
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
hr = pITS->Delete( szuName );
}
EXTENSION_RETURN_BOOL( SUCCEEDED( hr ) );
}
///////////////////////////////////////////////////////////////////////
//
XS(XS_Win32__Scheduler_TIE_DESTROY)
{
dXSARGS;
EXTENSION_VARS;
HV *phvSelf;
SV *pSvSelf = NULL;
ITaskScheduler *pITS = NULL;
if( 1 != items )
{
croak( "Usage: " EXTENSION "::DESTROY( $Self )\n" );
}
// DESTROY
phvSelf = (HV*) SvRV( ST( 0 ) );
pITS = (ITaskScheduler *) HASH_GET_IV( phvSelf, KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
pITS->Release();
}
XSRETURN_EMPTY;
}