# Include <windows. h>
# Include <stdio. h>
# Include "hash. H"
# Include "Debug. H"
# Include "stdio. H"
# Include "mytime. H"
# Define serv_name "uplsserver"
// DWORD winapi run (lpvoid lpparam );
DWORD winapi run (char * argv0, char * argv1, char * argv2); // three parameters are required for a function that actually works.
Static service_status servicestatus;
Static service_status_handle hstatus;
Static SC _handle schscmanager;
Static SC _handle schservice;
Void winapi controlhandler (DWORD request)
{
Switch (request ){
Case service_control_stop:
Log ("Service stopped! ");
Servicestatus. dwcurrentstate = service_stopped;
Servicestatus. dwwin32exitcode = 0;
Break;
Case service_control_pause:
Servicestatus. dwcurrentstate = service_paused;
Break;
Case service_control_continue:
Servicestatus. dwcurrentstate = service_running;
Break;
Case service_control_shutdown:
Break;
Case service_control_interrogate:
Break;
Default:
Break;
}
If (setservicestatus (hstatus, & servicestatus) = 0)
Fprintf (stderr, "setservicestatus in controlhandler out switch error! /N ");
Return;
}
Static void getservicepath (char * path)
{
Lpquery_service_config lpsc;
Lpservice_description lpsd;
DWORD dwbytesneeded, cbbufsize, dwerror;
// Get a handle to the SCM database.
Schscmanager = openscmanager (
Null, // Local Computer
Null, // servicesactive Database
SC _manager_all_access); // full access rights
If (null = schscmanager)
{
Printf ("openscmanager failed (% d)/n", getlasterror ());
Return;
}
// Get a handle to the service.
Schservice = openservice (
Schscmanager, // SCM Database
Serv_name, // name of service
Service_query_config); // need query config access
If (schservice = NULL)
{
Printf ("openservice failed (% d)/n", getlasterror ());
Closeservicehandle (schscmanager );
Return;
}
// Get the configuration information.
If (! Queryserviceconfig (
Schservice,
Null,
0,
& Dwbytesneeded ))
{
Dwerror = getlasterror ();
If (error_insufficient_buffer = dwerror)
{
Cbbufsize = dwbytesneeded;
Lpsc = (lpquery_service_config) localalloc (lmem_fixed, cbbufsize );
}
Else
{
Printf ("queryserviceconfig failed (% d)", dwerror );
Goto cleanup;
}
}
If (! Queryserviceconfig (
Schservice,
Lpsc,
Cbbufsize,
& Dwbytesneeded ))
{
Printf ("queryserviceconfig failed (% d)", getlasterror ());
Goto cleanup;
}
If (! Queryserviceconfig2 (
Schservice,
Service_config_description,
Null,
0,
& Dwbytesneeded ))
{
Dwerror = getlasterror ();
If (error_insufficient_buffer = dwerror)
{
Cbbufsize = dwbytesneeded;
Lpsd = (lpservice_description) localalloc (lmem_fixed, cbbufsize );
}
Else
{
Printf ("queryserviceconfig2 failed (% d)", dwerror );
Goto cleanup;
}
}
If (! Queryserviceconfig2 (
Schservice,
Service_config_description,
(Lpbyte) lpsd,
Cbbufsize,
& Dwbytesneeded ))
{
Printf ("queryserviceconfig2 failed (% d)", getlasterror ());
Goto cleanup;
}
// Print the configuration information.
// Log (lpsc-> lpbinarypathname );
Strcpy (path, lpsc-> lpbinarypathname );
Localfree (lpsc );
Localfree (lpsd );
Cleanup:
Closeservicehandle (schservice );
Closeservicehandle (schscmanager );
}
Static void winapi servicemain (INT argc, char * argv [])
{
Handle hthread;
DWORD dwerrorcode = 0;
Char path [256], argS [4] [128];
Int J = 0, K = 0, I = 0;
Servicestatus. dwservicetype = service_win32;
Servicestatus. dwcurrentstate = service_start_pending;
Servicestatus. dwcontrolsaccepted = service_accept_stop | service_accept_pause_continue;
Servicestatus. dwcheckpoint = 0;
Servicestatus. dwservicespecificexitcode = 0;
Servicestatus. dwwaithint = 0;
Servicestatus. dwwin32exitcode = 0;
Hstatus = registerservicectrlhandler (serv_name, controlhandler );
If (hstatus = (service_status_handle) 0 ){
Dwerrorcode = getlasterror ();
If (dwerrorcode = error_invalid_name ){
}
Else if (dwerrorcode = error_service_does_not_exist ){
}
Return;
}
Servicestatus. dwcurrentstate = service_running;
Servicestatus. dwcheckpoint = 0;
Servicestatus. dwwaithint = 0;
Setservicestatus (hstatus, & servicestatus );
Getservicepath (PATH );
For (I = 0; path [I]! = '/0'; I ++)
{
If (path [I] = '')
{
ARGs [J] [k] = '/0 ';
J ++;
K = 0;
Continue;
}
ARGs [J] [k] = path [I];
K ++;
}
ARGs [J] [k-1] = '/0 ';
Run (ARGs [1], argS [2], argS [3]);
/*
Hthread = createthread (null, 0, run, (lpvoid) & ARGs [0], 0, null );
If (hthread = NULL)
{
Printf ("create thread error! ");
Return;
}
Closehandle (hthread );
*/
Return;
}
Static void installservice (INT argc, char * argv [])
{
DWORD dwerrorcode;
Char szfilepath [64], szcmd [256];
Getmodulefilename (null, szfilepath, 255 );
Sprintf (szcmd, "% S % s", szfilepath, argv [0], argv [1], argv [2]);
Schscmanager = openscmanager (null, null, SC _manager_all_access );
If (schscmanager = NULL ){
Fprintf (stderr, "Open SCM database failed! /N ");
Return;
}
Schservice = createservice (schscmanager,
Serv_name,
Serv_name,
Service_all_access,
Service_win32_own_process/* | service_interactive_process */,
Service_auto_start,
Service_error_ignore,
Szcmd,
Null,
Null,
Null,
Null,
Null );
If (schservice = NULL ){
Dwerrorcode = getlasterror ();
If (dwerrorcode! = Error_service_exists ){
Fprintf (stderr, "create service failed! /N ");
Closeservicehandle (schscmanager );
}
Else {
Fprintf (stderr, "service already exists! /N ");
Closeservicehandle (schscmanager );
}
Return;
}
Else
Fprintf (stderr, "Install service successfully! /N ");
Schservice = openservice (schscmanager, serv_name, service_all_access );
If (schservice = NULL ){
Fprintf (stderr, "open service failed! /N ");
Closeservicehandle (schscmanager );
Return;
}
If (startservice (schservice, 0, null) = 0 ){
Dwerrorcode = getlasterror ();
If (dwerrorcode = error_service_already_running ){
Closeservicehandle (schscmanager );
Closeservicehandle (schservice );
Return;
}
}
While (queryservicestatus (schservice, & servicestatus )! = 0 ){
If (servicestatus. dwcurrentstate = service_start_pending)
Sleep (10 );
Else
Break;
}
If (servicestatus. dwcurrentstate = service_running)
Fprintf (stderr, "Start Service successfully! /N ");
Else
Fprintf (stderr, "Start Service failed! /N ");
Closeservicehandle (schscmanager );
Closeservicehandle (schservice );
Return;
}
Void uninstallservice ()
{
Service_status uninstallservicestatus;
Schscmanager = openscmanager (null, null, SC _manager_all_access );
If (schscmanager = NULL ){
Debugp ("Open SCM database failed! /N ");
Return;
}
Schservice = openservice (schscmanager, serv_name, service_all_access );
If (schservice = NULL ){
Debugp ("open service failed! /N ");
Closeservicehandle (schscmanager );
Return;
}
If (queryservicestatus (schservice, & uninstallservicestatus )! = 0 ){
If (uninstallservicestatus. dwcurrentstate! = Service_stopped ){
If (controlservice (schservice, service_control_stop, & uninstallservicestatus) = 0)
Fprintf (stderr, "Service stopped failed! /N ");
Sleep (100 );
If (uninstallservicestatus. dwcurrentstate = service_stopped)
Fprintf (stderr, "Service stopped successfully! /N ");
Else
Fprintf (stderr, "Service stopped failed! /N ");
}
Else
Fprintf (stderr, "service already stopped! /N ");
}
Else {
Fprintf (stderr, "Service Query failed! /N ");
Return;
}
If (deleteservice (schservice) = 0)
Fprintf (stderr, "uninstall service failed! /N ");
Else
Fprintf (stderr, "uninstall service successfully! /N ");
Closeservicehandle (schscmanager );
Closeservicehandle (schservice );
Return;
}
Int main (INT argc, char * argv [])
{
Service_table_entry servicetable [] = {
{Serv_name, (lpservice_main_function) servicemain },
{Null, null}
};
If (argc = 2 & _ stricmp (argv [1], "-Uninstall") = 0 ){
Uninstallservice ();
Return 0;
}
If (argc = 5 & _ stricmp (argv [1], "-install") = 0 ){
Installservice (3, & argv [2]);
Return 0;
}
Startservicectrldispatcher (servicetable );
Return 0;
}
Usage:
Service argv [0] argv [1] argv [2]-install
Service-uninstall