From e0635226917cf059973c848554bb9a6db427bc17 Mon Sep 17 00:00:00 2001 From: Mindaugas Kavaliauskas Date: Tue, 4 Oct 2016 16:22:56 +0300 Subject: [PATCH] 2016-10-04 16:22 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) * contrib/hbwin/hbwin.ch + WIN_SERVICE_CONTROL_SHUTDOWN define added * contrib/hbwin/win_svc_1.c + implemented capability to have custom service control handler. win_serviceStart() optional parameter added: win_serviceStart( cName, bEntryFunc | sEntryFunc [, bControlFunc | sControlFunc ] ) The minimal control function implementation is: PROC SvcControl(nControl) IF nControl == WIN_SERVICE_CONTROL_STOP .OR. ; nControl == WIN_SERVICE_CONTROL_SHUTDOWN win_serviceSetStatus(WIN_SERVICE_STOP_PENDING) ENDIF RETURN If control function parameter is passed, service state will not be set to running by default. This allows to abort service on startup. If service is started, service main function should set running status by calling win_serviceSetStatus(WIN_SERVICE_RUNNING) --- ChangeLog.txt | 19 ++++++++++++++++++ contrib/hbwin/hbwin.ch | 1 + contrib/hbwin/win_svc_1.c | 41 +++++++++++++++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 08a9e41288..f0c179011b 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,25 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2016-10-04 16:22 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + * contrib/hbwin/hbwin.ch + + WIN_SERVICE_CONTROL_SHUTDOWN define added + * contrib/hbwin/win_svc_1.c + + implemented capability to have custom service control handler. win_serviceStart() + optional parameter added: + win_serviceStart( cName, bEntryFunc | sEntryFunc [, bControlFunc | sControlFunc ] ) + The minimal control function implementation is: + PROC SvcControl(nControl) + IF nControl == WIN_SERVICE_CONTROL_STOP .OR. ; + nControl == WIN_SERVICE_CONTROL_SHUTDOWN + win_serviceSetStatus(WIN_SERVICE_STOP_PENDING) + ENDIF + RETURN + If control function parameter is passed, service state will not be set + to running by default. This allows to abort service on startup. + If service is started, service main function should set running status + by calling win_serviceSetStatus(WIN_SERVICE_RUNNING) + 2016-10-02 23:20 UTC+0400 Phil Krylov (phil a t newstar.rinet.ru) * config/global.mk ! Fix cross-compiler detection when only HB_CCPREFIX is passed from diff --git a/contrib/hbwin/hbwin.ch b/contrib/hbwin/hbwin.ch index 185915bb2b..aa36a25b04 100644 --- a/contrib/hbwin/hbwin.ch +++ b/contrib/hbwin/hbwin.ch @@ -677,6 +677,7 @@ #define WIN_SERVICE_CONTROL_PAUSE 0x00000002 #define WIN_SERVICE_CONTROL_CONTINUE 0x00000003 #define WIN_SERVICE_CONTROL_INTERROGATE 0x00000004 +#define WIN_SERVICE_CONTROL_SHUTDOWN 0x00000005 #define WIN_SERVICE_CONTROL_PARAMCHANGE 0x00000006 #define WIN_SERVICE_CONTROL_NETBINDADD 0x00000007 #define WIN_SERVICE_CONTROL_NETBINDREMOVE 0x00000008 diff --git a/contrib/hbwin/win_svc_1.c b/contrib/hbwin/win_svc_1.c index 00d3d42a01..8244400a27 100644 --- a/contrib/hbwin/win_svc_1.c +++ b/contrib/hbwin/win_svc_1.c @@ -58,21 +58,40 @@ static SERVICE_STATUS s_ServiceStatus; static SERVICE_STATUS_HANDLE s_hStatus; static PHB_ITEM s_pHarbourEntryFunc = NULL; +static PHB_ITEM s_pHarbourControlFunc = NULL; static TCHAR s_lpServiceName[ 256 ]; /* Control handler function */ static VOID WINAPI hbwin_SvcControlHandler( DWORD fdwControl ) { + if( s_pHarbourControlFunc ) + { + if( hb_vmRequestReenterExt() ) + { + hb_vmPushEvalSym(); + hb_vmPush( s_pHarbourControlFunc ); + hb_vmPushNumInt( ( HB_MAXINT ) fdwControl ); + hb_vmSend( 1 ); + hb_vmRequestRestore(); + } + else + HB_TRACE( HB_TR_DEBUG, ( "HVM stack not available" ) ); + return; + } + switch( fdwControl ) { case SERVICE_CONTROL_STOP: s_ServiceStatus.dwWin32ExitCode = 0; s_ServiceStatus.dwCurrentState = SERVICE_STOPPED; - return; + break; case SERVICE_CONTROL_SHUTDOWN: s_ServiceStatus.dwWin32ExitCode = 0; s_ServiceStatus.dwCurrentState = SERVICE_STOPPED; + break; + + default: return; } @@ -100,9 +119,12 @@ static VOID WINAPI hbwin_SvcMainFunction( DWORD dwArgc, LPTSTR * lpszArgv ) DWORD i; int iArgCount = 0; - /* We report the running status to SCM. */ - s_ServiceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus( s_hStatus, &s_ServiceStatus ); + if( ! s_pHarbourControlFunc ) + { + /* We report the running status to SCM. */ + s_ServiceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus( s_hStatus, &s_ServiceStatus ); + } hb_vmPushEvalSym(); hb_vmPush( s_pHarbourEntryFunc ); @@ -207,6 +229,17 @@ HB_FUNC( WIN_SERVICESTART ) if( pEntryFunc ) s_pHarbourEntryFunc = hb_itemNew( pEntryFunc ); + if( s_pHarbourControlFunc ) + { + hb_itemRelease( s_pHarbourControlFunc ); + s_pHarbourControlFunc = NULL; + } + + pEntryFunc = hb_param( 3, HB_IT_EVALITEM ); + + if( pEntryFunc ) + s_pHarbourControlFunc = hb_itemNew( pEntryFunc ); + lpServiceTable[ 0 ].lpServiceName = s_lpServiceName; lpServiceTable[ 0 ].lpServiceProc = ( LPSERVICE_MAIN_FUNCTION ) hbwin_SvcMainFunction;