Thread overview
service.d -- a skeletal service for Windows
May 27, 2004
Gifford Hesketh
May 27, 2004
David L. Davis
May 28, 2004
J C Calvarese
May 28, 2004
David L. Davis
May 28, 2004
Gifford Hesketh
May 28, 2004
David L. Davis
May 27, 2004
/*
** 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
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 28, 2004
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 28, 2004
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
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
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 28, 2004
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 ) );