//
// TPLmote CONTROL 
// Bastien BOURINEAU
//


#include "scolplugin.h"
#include <mmsystem.h>	// for timeGetTime
#include <stdio.h>

//#define		_SCOL_DEBUG_


cbmachine	ww;
mmachine	mm;


//////////////////////////////////////////////////////////////////////////////////////////////
///		_SystemShutDown
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[I] I
int _SystemShutDown(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_SystemShutDown\n");
#endif
	int  mode;

	mode = MTOI (MMpull(m));

	if ( mode == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	//http://www.codersource.net/mfc_shutdown_timer.html


	HANDLE hToken; // handle to process token 
	TOKEN_PRIVILEGES tkp; // pointer to token structure
	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); // Get the LUID for shutdown privilege.              
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
	tkp.PrivilegeCount = 1; // one privilege to set
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
	// Get shutdown privilege for this process. 
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
	// Cannot test the return value of AdjustTokenPrivileges.  
	if (GetLastError() != ERROR_SUCCESS)
	{
		MMechostr(0,"_SystemShutDown Privilege Error\n") ;
		MMset(m,0,NIL) ;
		return 0 ;
	}
	
	int nArgument;

	switch(mode)
	{

	case 0:nArgument=EWX_REBOOT; break;
	case 1:nArgument=EWX_SHUTDOWN; break;
	case 2:nArgument=EWX_POWEROFF; break;
	case 3:nArgument=EWX_LOGOFF;

	}
	
	// EWX_FORCE
	ExitWindowsEx(nArgument,EWX_FORCEIFHUNG);
	MMpush(m, 0);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		_SystemPowerState
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[I] I
int _SystemPowerState(mmachine m)
{
#ifdef _SCOL_DEBUG_
	MMechostr(0,"_SystemPowerState\n");
#endif

	int  mode;

	mode = MTOI (MMpull(m));

	if ( mode == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	//http://www.codersource.net/mfc_shutdown_timer.html


	HANDLE hToken; // handle to process token 
	TOKEN_PRIVILEGES tkp; // pointer to token structure
	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); // Get the LUID for shutdown privilege.              
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
	tkp.PrivilegeCount = 1; // one privilege to set
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
	// Get shutdown privilege for this process. 
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
	// Cannot test the return value of AdjustTokenPrivileges.  
	if (GetLastError() != ERROR_SUCCESS)
	{
		MMechostr(0,"_SystemPowerState Privilege Error\n") ;
		MMset(m,0,NIL) ;
		return 0 ;
	}
	
	bool fSuspend;

	switch(mode)
	{

	case 0:fSuspend=false; break;
	case 1:fSuspend=true;

	}

	if( !SetSystemPowerState( fSuspend, false) )
		MMpush(m, 0);
	else
		MMpush(m, -1);

#ifdef	_SCOL_DEBUG_
	MMechostr(0,"ok\n");
#endif

	return 0;
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////																											   ////
///										DECLARATION DES FONCTIONS POUR SCOL											///
////																											   ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



#define NbTplPKG	2


//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des noms de fonction SCOL
//////////////////////////////////////////////////////////////////////////////////////////////
char	*TplName[NbTplPKG] =
{
	"_SystemShutDown",
	"_SystemPowerState"

};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des pointeurs sur fonctions
//////////////////////////////////////////////////////////////////////////////////////////////
int (*TplFunc[NbTplPKG])(mmachine m)=
{
	_SystemShutDown,											// _SystemShutDown
	_SystemPowerState											// _SystemPowerState
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition du nombre de paramètres
//////////////////////////////////////////////////////////////////////////////////////////////
int TplNArg[NbTplPKG]=
{
	1,														// _SystemShutDown
	1														// _SystemPowerState
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des grammaires fontionnelles
//////////////////////////////////////////////////////////////////////////////////////////////
char* TplType[NbTplPKG]=
{
	"fun [I] I",											// _SystemShutDown
	"fun [I] I"												// _SystemPowerState
};





///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////																											   ////
///											FONCTIONS D'APPEL DE LA DLL												///
////																											   ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



int LoadWSystem(mmachine m)
{
	int			k;

	//$BLG - v5.24: Del
	//MMechostr(0,"\n" );
	//MMechostr(0,"*************************    WindowsSystem Support   *************************\n" );

	k = PKhardpak(m, "WSystemEngine", NbTplPKG, TplName, TplFunc, TplNArg, TplType);

	//$BLG - v5.24: Del
	//MMechostr(0,"**********************  Successfully Loaded  **********************\n" );
	//MMechostr(0,"\n" );

	return k;
}


///////////////////////////////////////////////////////////////
///		Starting point of the DLL							///
///////////////////////////////////////////////////////////////
extern "C" __declspec (dllexport) int ScolLoadPlugin(mmachine m, cbmachine w)
{
	int		k = 0;
	ww = w;
	mm = m;

	LoadWSystem(m);
	return k;
}

///////////////////////////////////////////////////////////////
///		Ending point of the DLL								///
///////////////////////////////////////////////////////////////
extern "C" __declspec (dllexport) int ScolUnloadPlugin()
{
  return 0;
}