service_api example ?

Discussions related to Visual Prolog
Gildas Menier
VIP Member
Posts: 78
Joined: 8 Jun 2004 23:01

service_api example ?

Unread post by Gildas Menier » 9 Apr 2009 16:58

Hi !

Has someone used the service_api (and would be kind to share an example ? ;) )

many thanks !

Regards

Gildas

Gildas Menier
VIP Member
Posts: 78
Joined: 8 Jun 2004 23:01

Unread post by Gildas Menier » 12 Apr 2009 22:20

Finally, I managed to build a service in VisualProlog (with start/stop/resume/suspend/install/delete). It works fine. Some (preliminary) remarks :
The service_api is a good start but, in my opinion lacks some important features :

first, the MSDN constants (for instance) :

Code: Select all

sERVICE_CONTROL_STOP           =0x00000001. sERVICE_CONTROL_PAUSE          =0x00000002. sERVICE_CONTROL_CONTINUE       =0x00000003. sERVICE_CONTROL_INTERROGATE    =0x00000004. sERVICE_CONTROL_SHUTDOWN       =0x00000005. sERVICE_CONTROL_PARAMCHANGE    =0x00000006. sERVICE_CONTROL_NETBINDADD     =0x00000007. sERVICE_CONTROL_NETBINDREMOVE  =0x00000008. sERVICE_CONTROL_NETBINDENABLE  =0x00000009. sERVICE_CONTROL_NETBINDDISABLE = 0x0000000A.   sERVICE_STOPPED                  =  0x00000001. sERVICE_START_PENDING       =      0x00000002. sERVICE_STOP_PENDING         =     0x00000003. sERVICE_RUNNING                  = 0x00000004. sERVICE_CONTINUE_PENDING  =     0x00000005. sERVICE_PAUSE_PENDING       =   0x00000006. sERVICE_PAUSED                   =    0x00000007.   sERVICE_ACCEPT_STOP                     =       0x00000001. sERVICE_ACCEPT_PAUSE_CONTINUE   =  0x00000002. sERVICE_ACCEPT_SHUTDOWN            =   0x00000004. sERVICE_ACCEPT_PARAMCHANGE       =   0x00000008. sERVICE_ACCEPT_NETBINDCHANGE    = 0x00000010.   sC_MANAGER_CONNECT                     =  0x0001. sC_MANAGER_CREATE_SERVICE         =   0x0002. sC_MANAGER_ENUMERATE_SERVICE   = 0x0004. sC_MANAGER_LOCK                           =  0x0008. sC_MANAGER_QUERY_LOCK_STATUS   =  0x0010. sC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020.   sC_MANAGER_ALL_ACCESS = 0xF003F.     sERVICE_QUERY_CONFIG           = 0x0001. sERVICE_CHANGE_CONFIG         = 0x0002. sERVICE_QUERY_STATUS           = 0x0004. sERVICE_ENUMERATE_DEPENDENTS  =  0x0008. sERVICE_START                  = 0x0010. sERVICE_STOP                   = 0x0020. sERVICE_PAUSE_CONTINUE        = 0x0040. sERVICE_INTERROGATE           =  0x0080. sERVICE_USER_DEFINED_CONTROL  =  0x0100.   sERVICE_ALL_ACCESS                = 0xF01FF.   sERVICE_WIN32_OWN_PROCESS = 0x00000010. sERVICE_WIN32_SHARE_PROCESS = 0x00000020. sERVICE_DEMAND_START           = 0x00000003. sERVICE_ERROR_NORMAL           = 0x00000001.     eRROR_SERVICE_SPECIFIC_ERROR = 0x1066. nO_ERROR = 0x00.
then StartServiceCTRLDispatcher / service_table_entry:

Code: Select all

startServiceCtrlDispatcher(service_native::service_table_entry(ServiceName, uncheckedconvert(pointer, serviceMain)))
should be called with an array of 2 service_table_entry, the last being (null,null) so I suggest the use of :

Code: Select all

domains     service_table_entryDomain = service_table_entry_util(string, pointer, string, pointer).
for the following call :

Code: Select all

            startServiceCtrlDispatcher(                 uncheckedconvert(service_native::service_table_entry,                        service_table_entry_util(ServiceName, uncheckedconvert(pointer, serviceMain), uncheckedconvert(string, null), null) ))
Another problem is the 'serviceMain' : this should be a WinAPI serviceMain(DWORD argc, LPTSTR*argv), so I suggest to add :

Code: Select all

domains     serviceDomain = (integer, pointer) procedure language C.
Samewise for the serviceCtrlHandler :

Code: Select all

    serviceHandlerDomain = (integer) procedure language C.
The following predicate is also very handy :

Code: Select all

       class predicates             sendStatusToSCM: (unsigned CurrentState, unsigned WIN32ExitCode, unsigned ServiceSpecificExitCode, unsigned CheckPoint, unsigned WaitHint) procedure (i,i,i,i,i).             clauses                sendStatusToSCM(CurrentState, WIN32ExitCode, ServiceSpecificExitCode, CheckPoint, WaitHint):-                     PServiceType = sERVICE_WIN32_OWN_PROCESS,                     PCurrentState = CurrentState,                                         if not(CurrentState = sERVICE_START_PENDING)                     then                         PControlsAccepted = bit::bitOr(sERVICE_ACCEPT_STOP, sERVICE_ACCEPT_SHUTDOWN, sERVICE_ACCEPT_PAUSE_CONTINUE)                     else                         PControlsAccepted = 0                     end if,                     if ServiceSpecificExitCode=0                     then                         PWIN32ExitCode = WIN32ExitCode                     else                         PWIN32ExitCode = eRROR_SERVICE_SPECIFIC_ERROR                     end if,                                         PServiceSpecificExitCode = ServiceSpecificExitCode,                     PWaitHint = WaitHint,                                         ServiceStatus = sERVICE_STATUS(PServiceType, PCurrentState, PControlsAccepted, PWIN32ExitCode, PServiceSpecificExitCode, CheckPoint, PWaitHint),                                         setServiceStatus(fserviceStatusHandle, uncheckedconvert(pointer, ServiceStatus))                                  .%
Regards

Gildas

Gildas Menier
VIP Member
Posts: 78
Joined: 8 Jun 2004 23:01

Unread post by Gildas Menier » 16 Apr 2009 8:31

I made a small set of predicates to ease the building of services in Visual Prolog. This may be a good start if you want to try services & service_api :

http://www.arsaniit.com/prolog-tools/me ... on/service

Regards

Gildas

Post Reply