Call SetServiceStatus( , SERVICE_STOPPED) in ServiceMain()

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am writing a service. Before exiting the ServiceMain(), I want to call
SetServiceStatus(hServiceHandle, SERVICE_STOPPED) to set the service status
to SERVICE_STOPPED, but the SetServiceStatus() function crash immediately.
For example:

ServiceMain(...)
{
SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;

...

MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus. ... (other values)
SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus); // this line
crash
MyLog("ServiceMain Existed"); // this line never reach.
}

Any idea? or I don't need to call SetServiceStatus(hServiceHandle,
SERVICE_STOPPED) to set the service status to SERVICE_STOPPED in the
ServiceMina()?

Thanks in advance,
lauch2.
 
lauch2 said:
I am writing a service. Before exiting the ServiceMain(), I want to call
SetServiceStatus(hServiceHandle, SERVICE_STOPPED) to set the service
status
to SERVICE_STOPPED, but the SetServiceStatus() function crash immediately.
For example:

ServiceMain(...)
{
SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;

...

MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus. ... (other values)
SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus); // this line
crash
MyLog("ServiceMain Existed"); // this line never reach.
}

This might help.


//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;


if ( !bDebug ) // when debugging we don't report to the SCM
{
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 = dwCheckPoint++;

// Report the status of the service to the service control manager.
//
if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus)))
{
AddToMessageLog(L"SetServiceStatus");
}
}
return fResult;
}


void WINAPI service_main(DWORD dwArgc, PWSTR *lpszArgv)
{

// register our service control handler:
//
sshStatusHandle = RegisterServiceCtrlHandler( SZSERVICENAME,
service_ctrl);

if (sshStatusHandle != NULL)
{

// SERVICE_STATUS members that don't change in example
//
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;


// report the status to the service control manager.
//
if (ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
ServiceStart( dwArgc, lpszArgv );

// try to report the stopped status to the service control manager.
//

ReportStatusToSCMgr(SERVICE_STOPPED, dwErr,0);
}
return;
}
 
Back
Top