#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <initguid.h>
#include <ole2.h>
#include <mstask.h>
#include <msterr.h>
#include <wtypes.h>
#include <tchar.h>
#ifdef __BORLANDC__
typedef wchar_t wctype_t; /* in tchar.h, but unavailable unless _UNICODE */
#endif
#include <stdio.h> // Gurusamy's right, Borland is brain damaged!
#include <math.h> // Gurusamy's right, MS is brain damaged!
#define MYWORD_TEMP WORD
// If we are building with the core distribution headers we can not define
// the function names using C++ because of name mangling
#if defined(__cplusplus) && !defined(PERL_OBJECT)
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSub.h"
#if defined(__cplusplus) && !defined(PERL_OBJECT)
}
#endif
#ifdef WORD
#undef WORD
#define WORD MYWORD_TEMP
#endif // WORD
#include "constant.h"
#include "CUString.hpp"
#include "Scheduler.hpp"
#include "TIE_Scheduler.xpp"
#include "TIE_Task.xpp"
/*----------------------- M I S C F U N C T I O N S -------------------*/
DWORD FindSubString( LPTSTR pszString, LPTSTR pszSubString )
{
TCHAR tChar;
DWORD dwCount = 0;
DWORD dwSubLength = _tcslen( pszSubString );
while( '\0' != pszString[0] )
{
dwCount++;
if( _tolower( pszString[0] ) == _tolower( pszSubString[0] ) )
{
if( 0 == _tcsnicmp( pszString, pszSubString, dwSubLength ) )
{
return( dwCount );
}
}
pszString++;
}
return( 0 );
}
/*----------------------- P E R L F U N C T I O N S -------------------*/
//////////////////////////////////////////////////////////////////
XS( XS_WIN32__Scheduler_Constant )
{
dXSARGS;
EXTENSION_VARS;
char *pszName = NULL;
LPVOID pBuffer = NULL;
DWORD dwValue;
eConstantType eResult;
if( 2 != items )
{
croak( "Usage: " EXTENSION "::Constant( $Name, $Arg )\n" );
}
pszName = (char*) SvPV( ST( 0 ), na );
eResult = Constant( pszName, &pBuffer );
switch( eResult )
{
case String:
sv_setpv( ST( 1 ), (char*) pBuffer );
break;
case Numeric:
sv_setiv( ST( 1 ), (IV) pBuffer );
break;
}
// Return the result type.
PUSH_IV( eResult );
EXTENSION_RETURN;
}
//////////////////////////////////////////////////////////////////
XS( XS_Win32__Scheduler_QueryInterface )
{
dXSARGS;
EXTENSION_VARS;
DWORD dwResult = 0;
ITaskScheduler *pITS = NULL;
if( 1 != items )
{
croak( TEXT( "Usage: " EXTENSION "::QueryInterface()\n" ) );
}
pITS = (ITaskScheduler *) HASH_GET_IV( EXTRACT_HV( ST( 0 ) ), KEYWORD_SCHEDULER_INTERFACE );
if( NULL != pITS )
{
PUSH_IV( pITS );
}
EXTENSION_RETURN;
}
//////////////////////////////////////////////////////////////////
XS( XS_Win32__Scheduler_Task_QueryInterface )
{
dXSARGS;
EXTENSION_VARS;
DWORD dwResult = 0;
ITask *pTask = NULL;
if( 1 != items )
{
croak( TEXT( "Usage: " EXTENSION "::QueryInterface()\n" ) );
}
pTask = (ITask *) HASH_GET_IV( EXTRACT_HV( ST( 0 ) ), KEYWORD_TASK_INTERFACE );
if( NULL != pTask )
{
PUSH_IV( pTask );
}
EXTENSION_RETURN;
}
//////////////////////////////////////////////////////////////////
XS( XS_WIN32__Scheduler_Enum )
{
dXSARGS;
EXTENSION_VARS;
DWORD dwTotal = 0;
HV *pHv = NULL;
if( 1 != items )
{
croak( TEXT( "Usage: " EXTENSION "::Enum( \\%List )\n" ) );
}
if( NULL != ( pHv = EXTRACT_HV( ST( 0 ) ) ) )
{
IEnumWorkItems *pIEnum;
HRESULT hr = gpITS->Enum(&pIEnum);
if( SUCCEEDED( hr ) )
{
/////////////////////////////////////////////////////////////////
// Call IEnumWorkItems::Next to retrieve tasks. Note that
// this example tries to retrieve five tasks for each call.
/////////////////////////////////////////////////////////////////
LPWSTR *pszwNames;
DWORD dwTasks = 0;
DWORD dwTasksToFetch = TOTAL_TASKS_TO_RETRIEVE;
while( SUCCEEDED( pIEnum->Next( dwTasksToFetch,
&pszwNames,
&dwTasks ) )
&& ( 0 != dwTasks ) )
{
CUString szuString;
///////////////////////////////////////////////////////////////
// Process each task. Note that this example prints the
// name of each task to the screen.
//////////////////////////////////////////////////////////////
while( dwTasks )
{
szuString = pszwNames[ --dwTasks ];
CoTaskMemFree( pszwNames[ dwTasks ] );
dwTotal++;
HASH_STORE_PV( pHv, KEYWORD_HASH_NAME, (LPTSTR) szuString );
}
CoTaskMemFree( pszwNames );
}
pIEnum->Release();
}
}
PUSH_IV( dwTotal );
EXTENSION_RETURN;
}
//////////////////////////////////////////////////////////////////
XS( boot_Win32__Scheduler )
{
dXSARGS;
EXTENSION_VARS;
LPTSTR file = __FILE__;
int retcode = 1;
XS_VERSION_BOOTCHECK ;
newXS( EXTENSION "::Constant", XS_WIN32__Scheduler_Constant, file );
newXS( EXTENSION "::Enum", XS_WIN32__Scheduler_Enum, file );
newXS( EXTENSION "::TIEHASH", XS_Win32__Scheduler_TIE_HASH, file);
newXS( EXTENSION "::FETCH", XS_Win32__Scheduler_TIE_FETCH, file);
newXS( EXTENSION "::STORE", XS_Win32__Scheduler_TIE_STORE, file);
newXS( EXTENSION "::FIRSTKEY", XS_Win32__Scheduler_TIE_FIRSTKEY, file);
newXS( EXTENSION "::NEXTKEY", XS_Win32__Scheduler_TIE_NEXTKEY, file);
newXS( EXTENSION "::EXISTS", XS_Win32__Scheduler_TIE_EXISTS, file);
newXS( EXTENSION "::CLEAR", XS_Win32__Scheduler_TIE_CLEAR, file);
newXS( EXTENSION "::DELETE", XS_Win32__Scheduler_TIE_DELETE, file);
newXS( EXTENSION "::DESTROY", XS_Win32__Scheduler_TIE_DESTROY, file);
newXS( EXTENSION "::QueryInterface", XS_Win32__Scheduler_QueryInterface, file);
// newXS( EXTENSION "::Task::TIEHASH", XS_Win32__Scheduler_Task_TIE_HASH, file);
newXS( EXTENSION "::Task::FETCH", XS_Win32__Scheduler_Task_TIE_FETCH, file);
newXS( EXTENSION "::Task::STORE", XS_Win32__Scheduler_Task_TIE_STORE, file);
newXS( EXTENSION "::Task::FIRSTKEY", XS_Win32__Scheduler_Task_TIE_FIRSTKEY, file);
newXS( EXTENSION "::Task::NEXTKEY", XS_Win32__Scheduler_Task_TIE_NEXTKEY, file);
newXS( EXTENSION "::Task::EXISTS", XS_Win32__Scheduler_Task_TIE_EXISTS, file);
// newXS( EXTENSION "::Task::CLEAR", XS_Win32__Scheduler_Task_TIE_CLEAR, file);
newXS( EXTENSION "::Task::DELETE", XS_Win32__Scheduler_Task_TIE_DELETE, file);
newXS( EXTENSION "::Task::DESTROY", XS_Win32__Scheduler_Task_TIE_DESTROY, file);
newXS( EXTENSION "::Task::QueryInterface", XS_Win32__Scheduler_Task_QueryInterface, file);
XSRETURN_YES;
}
/* =============== DLL Specific Functions =================== */
//////////////////////////////////////////////////////////////////
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
BOOL fResult = TRUE;
HRESULT hr = ERROR_SUCCESS;
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
gdwThread = 1;
ghDLL = hinstDLL;
CountConstants();
hr = CoInitialize( NULL );
if ( SUCCEEDED( hr ) )
{
hr = CoCreateInstance( CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(void **) &gpITS );
if( FAILED( hr ) )
{
CoUninitialize();
fResult = FALSE;
}
}
break;
case DLL_THREAD_ATTACH:
gdwThread++;
break;
case DLL_THREAD_DETACH:
gdwThread--;
break;
case DLL_PROCESS_DETACH:
gpITS->Release();
CoUninitialize();
break;
default:
break;
}
return( fResult );
}