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;