www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - service.d -- a skeletal service for Windows

reply "Gifford Hesketh" <gifford.hesketh savvis.net> writes:
/*
** service.d -- a skeletal service for Windows
**
** Created 2004-May-27 for the public domain by Gifford Hesketh  (
first.last gmail.com )
*/
import winbase;
import winerror;
import winnt;
import winsvc;

extern ( Windows )
{

char * theServiceName = "service.d";

int main ( char[][] args )
{
 SERVICE_TABLE_ENTRY[] theServiceTable;
 theServiceTable.length = 2;

 theServiceTable[ 0 ].lpServiceName = theServiceName;
 theServiceTable[ 0 ].lpServiceProc = & ( ServiceMain );
 theServiceTable[ 1 ].lpServiceName = null;
 theServiceTable[ 1 ].lpServiceProc = null;

 if ( ! ( StartServiceCtrlDispatcher ( theServiceTable ) ) )
 {
  /*
  ** probably (?) run from the command line
  */
  void * theSCM;

  OutputDebugString ( "! StartServiceCtrlDispatcher" );

  theSCM = OpenSCManager ( null, null, SC_MANAGER_CREATE_SERVICE | DELETE );

  if ( cast ( SC_HANDLE ) 0 != theSCM )
  {
   void * theService;

   theService = OpenService ( theSCM, theServiceName, DELETE );

   if ( cast ( SC_HANDLE ) 0 != theService )
   {
    /*
    ** service exists; delete it
    */
    if ( DeleteService ( theService ) )
    {
     OutputDebugString ( ". DeleteService" );
    }
    else
    {
     OutputDebugString ( "! DeleteService" );
    }

    CloseServiceHandle ( theService );
   }
   else
   {
    if ( ERROR_SERVICE_DOES_NOT_EXIST == GetLastError () )
    {
     /*
     ** service does not exist; create it
     */
     theService = CreateService ( theSCM, theServiceName, theServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, args[ 0 ], null, null, null, null, null );

     if ( cast ( SC_HANDLE ) 0 == theService )
     {
      OutputDebugString ( "! CreateService" );
     }
     else
     {
      OutputDebugString ( ". CreateService" );

      CloseServiceHandle ( theService );
     }
    }
   }

   CloseServiceHandle ( theSCM );

  }

 }
 else
 {
  /*
  ** the service has finished running
  */
  OutputDebugString ( ". StartServiceCtrlDispatcher" );
 }

 return 0;

} // main ()


/*
** the name of this function is arbitrary
*/
void ServiceMain ( uint dwArgc, char * * lpszArgv )
{
 void * theEvent;
 SERVICE_STATUS theServiceStatus;
 SERVICE_STATUS_HANDLE theServiceStatusHandle;

 theServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
 theServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_PARAMCHANGE;
 theServiceStatus.dwWin32ExitCode = 0;
 theServiceStatus.dwServiceSpecificExitCode = 0;
 theServiceStatus.dwCheckPoint = 0;
 theServiceStatus.dwWaitHint = 0;

 theServiceStatusHandle = RegisterServiceCtrlHandler ( theServiceName, & (
ServiceCtrlHandler ) );

 if ( cast ( SERVICE_STATUS_HANDLE ) 0 == theServiceStatusHandle )
 {
  OutputDebugString ( "! RegisterServiceCtrlHandlerEx" );
 }
 else
 {
  OutputDebugString ( ". RegisterServiceCtrlHandlerEx" );
 }

 theServiceStatus.dwCurrentState = SERVICE_START_PENDING;

 if ( ! SetServiceStatus ( theServiceStatusHandle, &theServiceStatus))
 {
  OutputDebugString ( "! SERVICE_START_PENDING" );
 }
 else
 {
  OutputDebugString ( ". SERVICE_START_PENDING" );
 }


 /*
 ** create a synchronization object so the control handler can notify when
to stop
 */
 theEvent = CreateEvent ( null, true, false, theServiceName );

 if ( null == theEvent )
 {
  theServiceStatus.dwCurrentState = SERVICE_STOPPED;

  if ( ! SetServiceStatus ( theServiceStatusHandle, & (
theServiceStatus ) ) )
  {
   OutputDebugString ( "! SERVICE_STOPPED" );
  }
  else
  {
   OutputDebugString ( ". SERVICE_STOPPED" );
  }

  return;
 }

 theServiceStatus.dwCurrentState = SERVICE_RUNNING;

 if ( ! SetServiceStatus ( theServiceStatusHandle, & (
theServiceStatus ) ) )
 {
  OutputDebugString ( "! SERVICE_RUNNING" );
 }
 else
 {
  OutputDebugString ( ". SERVICE_RUNNING" );
 }


 /*
 ** wait for notification to stop from the control handler
 */
 WaitForSingleObject ( theEvent, INFINITE );

 theServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;

 if ( ! SetServiceStatus ( theServiceStatusHandle, & (
theServiceStatus ) ) )
 {
  OutputDebugString ( "! SERVICE_STOP_PENDING" );
 }
 else
 {
  OutputDebugString ( ". SERVICE_STOP_PENDING" );
 }


 /*
 ** deref the synchronization object
 */
 CloseHandle ( theEvent );


 theServiceStatus.dwCurrentState = SERVICE_STOPPED;

 if ( ! SetServiceStatus ( theServiceStatusHandle, & (
theServiceStatus ) ) )
 {
  OutputDebugString ( "! SERVICE_STOPPED" );
 }
 else
 {
  OutputDebugString ( ". SERVICE_STOPPED" );
 }

 return;

} // ServiceMain ()


/*
** the name of this function is arbitrary
*/
void ServiceCtrlHandler ( uint dwControl )
{
 void * theEvent;

 switch ( dwControl )
 {
  case SERVICE_CONTROL_STOP:
   OutputDebugString ( ". SERVICE_CONTROL_STOP" );

   theEvent = OpenEvent ( EVENT_MODIFY_STATE, false, theServiceName );
   SetEvent ( theEvent );
   CloseHandle ( theEvent );

   break;

  case SERVICE_CONTROL_PAUSE:
   OutputDebugString ( ". SERVICE_CONTROL_PAUSE" );
   break;

  case SERVICE_CONTROL_CONTINUE:
   OutputDebugString ( ". SERVICE_CONTROL_CONTINUE" );
   break;

  case SERVICE_CONTROL_PARAMCHANGE:
   OutputDebugString ( ". SERVICE_CONTROL_PARAMCHANGE" );
   break;

  case SERVICE_CONTROL_INTERROGATE:
   OutputDebugString ( ". SERVICE_CONTROL_INTERROGATE" );
   break;

  case SERVICE_CONTROL_SHUTDOWN:
   OutputDebugString ( ". SERVICE_CONTROL_SHUTDOWN" );
   break;

  default:
   OutputDebugString ( ". ServiceCtrlHandler" );
   break;
 }

 return;

} // ServiceCtrlHandler ()

} // extern ( Windows )
May 27 2004
parent reply David L. Davis <David_member pathlink.com> writes:
Gifford: I really would like to take a good look at your work and download all
the .d files, but I'm not sure how grab the encrypted ones. I thought by setting
up my Outlook 2003 for this news group that it would help me over viewing this
site in IE 6, but they look exactly the same. (Go Figure!) 

Anyway, I have a strong interest in making a windows service, I want to rewrite
an old "C" audit program I wrote years ago that tracked program usage by user
and such. And since I'm really enjoying "D's" great support for strings...I'd
love to use D to recreate it with. Man, I've forgotten how many times I've had
to type in lines and lines of malloc()s, strcpy()s, strcat()s and such, just to
do the most simplest of string work. But with "D," no more of that sort of
thing!!! 

Also, if you have a web site with these files in a .zip, or .rar, or even a html
web page to copy & paste from, please point me to them!

Thanks in Advance. :)
May 27 2004
next sibling parent reply J C Calvarese <jcc7 cox.net> writes:
David L. Davis wrote:
 Gifford: I really would like to take a good look at your work and download all
 the .d files, but I'm not sure how grab the encrypted ones. I thought by
setting
 up my Outlook 2003 for this news group that it would help me over viewing this
 site in IE 6, but they look exactly the same. (Go Figure!) 

That's odd. I had no problem accessing these files in Mozilla Thunderbird. (I don't know why Outlook wouldn't be able to handle them.) I posted a .zip of the files at my website: http://jcc_7.tripod.com/d/win_service/index.html
 
 Anyway, I have a strong interest in making a windows service, I want to rewrite
 an old "C" audit program I wrote years ago that tracked program usage by user
 and such. And since I'm really enjoying "D's" great support for strings...I'd
 love to use D to recreate it with. Man, I've forgotten how many times I've had
 to type in lines and lines of malloc()s, strcpy()s, strcat()s and such, just to
 do the most simplest of string work. But with "D," no more of that sort of
 thing!!! 
 
 Also, if you have a web site with these files in a .zip, or .rar, or even a
html
 web page to copy & paste from, please point me to them!
 
 Thanks in Advance. :) 

-- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
May 27 2004
parent David L. Davis <David_member pathlink.com> writes:
J C Calvarese: Thanks, I've downloaded the D source code for a "Windows Service"
zip from your web site. 

I'm going to go back recheck my setup in Outlook, I must have done (or undone)
something. But "the Outlook help, isn't very helpful"...and this is the first
time I tried to set it up for a news group. Back to the drawing board. :)

Thxs Again!

P.S. And Gifford Hesketh, thanks for putting this code together to work with D!

In article <c968m1$2lf1$1 digitaldaemon.com>, J C Calvarese says...
That's odd. I had no problem accessing these files in Mozilla 
Thunderbird. (I don't know why Outlook wouldn't be able to handle them.) 
I posted a .zip of the files at my website: 
http://jcc_7.tripod.com/d/win_service/index.html

May 28 2004
prev sibling parent reply "Gifford Hesketh" <gifford.hesketh savvis.net> writes:
I have put the code up for browsing here:
    http://users.adelphia.net/~4187/gifford/src/d/service/

FWIW, the last issue I pinned down was how to make code using
"theServiceTable" compile and work.  When I first made this in in January or
Febrary, I had the variable declared as SERVICE_TABLE_ENTRY[2] -- and that
worked.  I have since updated to D 0.90, which would not succeed compiling
the same code (it was actually linking that failed).  I tried changing it to
SERVICE_TABLE_ENTRY *, but I could not figure out how to get malloc() to
happen.  The D code that worked
	SERVICE_TABLE_ENTRY[] theServiceTable;
	theServiceTable.length = 2;is functionally very much like the same code I
wrote in C:

    SERVICE_TABLE_ENTRY * pServiceTable;
    pServiceTable = ( SERVICE_TABLE_ENTRY * ) malloc ( 2 * sizeof (
SERVICE_TABLE_ENTRY ) );


"David L. Davis" <David_member pathlink.com> wrote in message
news:c95svk$258v$1 digitaldaemon.com...
 Gifford: I really would like to take a good look at your work and download

 the .d files, but I'm not sure how grab the encrypted ones. I thought by

 up my Outlook 2003 for this news group that it would help me over viewing

 site in IE 6, but they look exactly the same. (Go Figure!)

 Anyway, I have a strong interest in making a windows service, I want to

 an old "C" audit program I wrote years ago that tracked program usage by

 and such. And since I'm really enjoying "D's" great support for

 love to use D to recreate it with. Man, I've forgotten how many times I've

 to type in lines and lines of malloc()s, strcpy()s, strcat()s and such,

 do the most simplest of string work. But with "D," no more of that sort of
 thing!!!

 Also, if you have a web site with these files in a .zip, or .rar, or even

 web page to copy & paste from, please point me to them!

 Thanks in Advance. :)

May 28 2004
parent David L. Davis <SpottedTiger yahoo.com> writes:
Gifford: Thanks for putting the code up on to a web page, by the way, if I
create anything somewhat useful I'll share it with you, and anyone else who'll
find a use for it. I'm thinking of digging up that old "C" audit (program
usage/amount of time running/by user) code I was talking about before, if
nothing else it might ->service<- (:P) as some example code. If I recall
correctly, it was a simple but useful little app that ran in the background
creating text usage log file. We'll see. :))

Thxs Again! 

In article <c981h4$29aj$1 digitaldaemon.com>, Gifford Hesketh says...
I have put the code up for browsing here:
    http://users.adelphia.net/~4187/gifford/src/d/service/

FWIW, the last issue I pinned down was how to make code using
"theServiceTable" compile and work.  When I first made this in in January or
Febrary, I had the variable declared as SERVICE_TABLE_ENTRY[2] -- and that
worked.  I have since updated to D 0.90, which would not succeed compiling
the same code (it was actually linking that failed).  I tried changing it to
SERVICE_TABLE_ENTRY *, but I could not figure out how to get malloc() to
happen.  The D code that worked
	SERVICE_TABLE_ENTRY[] theServiceTable;
	theServiceTable.length = 2;is functionally very much like the same code I
wrote in C:

    SERVICE_TABLE_ENTRY * pServiceTable;
    pServiceTable = ( SERVICE_TABLE_ENTRY * ) malloc ( 2 * sizeof (
SERVICE_TABLE_ENTRY ) );

May 28 2004