TUTORIAL FOR ASM WINDOWS NT SERVICE: Many people are familiar with device drivers and their advantage at being autostarted by the system and getting Ring 0 privilege. But with that privilege comes complexity in both the planning and development phase. Microsoft's tendency to be less than forthcoming with information makes the task all the harder. By contrast many of us are familiar with programming at Ring 3 and the documentation of the Win32 API is extensive. Wouldn't it be nice to combine the characteristics of a driver with the familiarity of regular Ring 3 Apps. Services are Microsoft's attempt to create such a beast. They gain the advantage of being autostarted by the system while keeping the familiarity of normal Ring 3 programming. NOTE: I am restricting this discussion to NT because services under Win95/98 are an afterthought. The support consists fo a registry entry under ( HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersio n\RunServices ) and one API function RegisterServiceProcess. Creating a Win95 version of a service is left as an exercise for the reader. INSTALLING THE SERVICE: I have included a program to install and remove a service from the SCM Database. A step which is necessary before a service can be run. To install the service: tool /i beepserv "ASM Beepservice" path\beepserv.exe Then goto the service applet of the Control panel and find the ASM Beepservice click on it and it should start. To remove the service: tool /r beepserv INTRO: Services are simply normal programs with two threads. One thread is the worker which performs whatever actions you desire. The second is there to communicate with the OS, which will inform it when to Start, Stop, Pause, Initialize, and Terminate. Just like any other program a Service has an entry point here named start but it could be the infamous main. ;******************************************************** .code start: ;Register with the SCM mov sTable.lpServiceProc, offset ServiceMain LOAD sTable.lpServiceName, offset SERVICE_NAME INVOKE StartServiceCtrlDispatcher, ADDR sTable .IF eax == 0 INVOKE ErrorHandler, ADDR ERROR_MESSAGE .ENDIF INVOKE ExitProcess, eax ;******************************************************** This snippet of code does nothing but call StartServiceCtrlDispatcher and Exit. So where is the Service? Hidden behind StartServiceCtrlDispatcher. Basically start calls this function and does not return until the System tells the Service to terminate or there is a fatal error within the Service and it is terminated by the SCM. When the SCM receives this call it registers the Service with name SERVICE_NAME and associates it with the function ServiceMain. The SCM then calls the ServiceMain function (the service's entry point). SERVICEMAIN: The ServiceMain function does a number of things and here it is in stripped down form. ;******************************************************** ServiceMain proc argc:DWORD, argv:DWORD LOCAL success:BOOL LOCAL temp:DWORD ;immediately call Registration function INVOKE RegisterServiceCtrlHandler, ADDR SERVICE_NAME, CtrlHandler ;Notify SCM of progress INVOKE SendStatus, SERVICE_START_PENDING, NO_ERROR, 0, 1, 5000 ;create the termination event INVOKE CreateEvent, 0, TRUE, FALSE, 0 ;Notify SCM of progress INVOKE SendStatus, SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000 ;Notify SCM of progress INVOKE SendStatus, SERVICE_START_PENDING, NO_ERROR, 0, 3, 5000 ;Start the service itself call Init ;Notify SCM of progress INVOKE SendStatus, SERVICE_RUNNING, NO_ERROR, 0, 0, 0 ;Wait for stop signal, and then terminate INVOKE WaitForSingleObject, evTerminate, INFINITE push 0 call terminate ret ServiceMain endp ;******************************************************** This function is responsible for registration and initialization. The first thing it does is register the Service Control Handler. This is essentially a dispatch routine which receives and responds to request by the SCM to start, stop, pause, terminate, and tell me a little about yourself. The next thing you see is a call to SendStatus (many calls to it actually). All this function does is tell the SCM that the service is still running, is step n in its initialization, informs the SCM of what the status of the service is, and that it expects to send its status again within so many milliseconds ( 2000-5000 in the example above ). The next thing that is done is to create an Event. The purpose the Event is to prevent the ServiceMain from terminating (Notice the WaitForSingleObject call ) until the Event gets set. The Event gets set in the Stop function which is called by the CtrlHandler. CTRLHANDLER: The next function to examine is the CtrlHandler function. The CtrlHandler function is the interface to the SCM and behaves just like the familiar Message handling procedure in Windows. The CtrlHandler function is under some restrictions as to how it can behave and how long it has to respond to the SCM. Here are the various notes and rules. 1) Must accept and process the SERVICE_CONTROL_INTERROGATE control code. 2) Process messages in less than 30 seconds. 3) After receiving the SERVICE_CONTROL_SHUTDOWN control code the service has 20 seconds ( see 5 below ) before the system shuts down. 4) Services continue to run even after the Restart Dialog box appears, but there is no system. Hmmmm walk lightly carry and exception at this point. 5) There is a registry key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control with a value WaitToKillServiceTimeout which specifies how long a service has after receiving the SERVICE_CONTROL_SHUTDOWN control code the default is 20 sec. Other than the above rules the CtrlHandler is also responsible for performing any actions necessary to respond to the control codes sent to it. NOTES: Strangely by default services run under their own desktop. This is controled through the SERVICE_INTERACTIVE_PROCESS flag to the dwServiceType parameter of the CreateService function. Unless this flag is set the service cannot interact with the users desktop. This means no GUI no dialog boxes. Only the MessageBox function will work and only with the MB_SERVICE_NOTIFICATION flag set. This can be a source of great frustration (personal experience here). That about sums it up. Enjoy having this useful technique at your disposal. Cynical Pinnacle