29 August, 2007

Windows Service Simple Sample

Some years ago I was C/C++ developer and I wrote several windows services.
I know that writing of service programs is quite difficult for beginners.

In this post I'm publishing simple working example.
This service only beeps with one second's interval after starts.


service.c

#include <windows.h>

HANDLE hServerStopEvent = NULL;
VOID ServiceBody();
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
VOID WINAPI ServiceControlHandler(DWORD dwCtrlCode);
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);


SERVICE_STATUS ssStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;

void _cdecl main(int argc, char **argv)
{
SERVICE_TABLE_ENTRY dispatchTable[] =
{{"", (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL }};
StartServiceCtrlDispatcher(dispatchTable);
}

void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
sshStatusHandle = RegisterServiceCtrlHandler( "", ServiceControlHandler);

if (!sshStatusHandle)
goto cleanup;

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;

if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
goto cleanup;

ServiceBody();

cleanup:
if (sshStatusHandle)
(VOID)ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);
return;
}

VOID WINAPI ServiceControlHandler(DWORD dwCtrlCode)
{
if(dwCtrlCode==SERVICE_CONTROL_STOP)
{
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
if ( hServerStopEvent )
SetEvent(hServerStopEvent);
}
ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}

BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
{
if (dwCurrentState == SERVICE_START_PENDING)
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;

if ( ( dwCurrentState == SERVICE_RUNNING )
|| ( dwCurrentState == SERVICE_STOPPED ) )
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint++;

return SetServiceStatus( sshStatusHandle, &ssStatus);
}


//This sample only beeps.
VOID ServiceBody ()
{
hServerStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hServerStopEvent)
goto cleanup;

if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
goto cleanup;

do
{
MessageBeep(-1);
} while (WaitForSingleObject(hServerStopEvent, 1000 )== WAIT_TIMEOUT);

cleanup:
if (hServerStopEvent)
CloseHandle(hServerStopEvent);
}



Script for compiling with Visual C++ 6.0:

make_vc6.bat
@call "D:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
@cl /nologo service.c user32.lib advapi32.lib
@del service.obj

If you use Visual C++ Express, you need additional Platform SDK from Microsoft.

Install (register) service via command:

service_create.bat
sc create "XQX Service" binPath= %CD%\service.exe


Start service via command:

service_start.bat
net start "XQX Service"


Stop service via command:

service_stop.bat
net stop "XQX Service"


Uninstall (remove) service via command:

service_delete.bat
sc delete "XQX Service"

28 August, 2007

Blog locking

Last week my blog was locked by Blogger's spam-prevention robots...
It say:
Blogger's spam-prevention robots have detected that your blog has characteristics of a spam blog.

But today Blogger's operators have appologized:
Your blog has been reviewed, verified, and cleared for regular use so that
it will no longer appear as potential spam. If you sign out of Blogger and
sign back in again, you should be able to post as normal. Thanks for your
patience, and we apologize for any inconvenience this has caused.


And now I'm available again :-)