• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 214
  • Last Modified:

My Service crashes in XP machine and not in other OS

Requirement : I need to run a service in a XP machine from a remote windows (NT/2K/XP) machine using C program.
                     The service exe in the XP machine crashes after execution.

Description : I have "test.exe" ,a service exe , that calls "StartServiceCtrlDispatcher()" method. This exe is put in a specific location in
a XP Machine. I have another C program that will install (a service named 'Test') and run the service ('Test'), This C program will reside in a remote machine (NT/XP/2K). On running the service (using the C Program) test.exe will be exectuted.

The service in XP Machine is created using the 'local account'  (by passing username and password as NULL for CreateService() method).
When i run the service using StartService() method, the test.exe runs in the remote machine and crashes at the end.

What may be the reason that it crashes.???!!!

Hint  1 : This (crash) happens only when the test.exe is run in the XP machine. It works fine when run in any other Windows OS.
Hint  2 : after  debugging the C program (that installs/ runs the service), and putting some logs in the test.exe, i came to know that
             the crash happenned only after the COMPLETE execution of test.exe in the remote (XP machine). i.e, i was able to print a log at the
             last line of test.exe.

Does any one have an idea of where the problem could be??

-SRK
0
srk_karthik
Asked:
srk_karthik
1 Solution
 
Kent OlsenData Warehouse Architect / DBACommented:

Services typically run "forever" or until specifically stopped by another process (such as "Manage Services").

Does Test.exe tell the host O/S that it is terminating and will no longer be a running service?

Kent
0
 
srk_karthikAuthor Commented:
Yes, the following code in test.exe does that :

------------------------------------------------------------
SERVICE_STATUS          ServiceStatus;
SERVICE_STATUS_HANDLE   hStatus;

void
ControlHandler(DWORD request) {
   switch(request)
   {
      case SERVICE_CONTROL_STOP:
      case SERVICE_CONTROL_SHUTDOWN:
         ServiceStatus.dwWin32ExitCode = 0;
         ServiceStatus.dwCurrentState = SERVICE_STOPPED;
         SetServiceStatus (hStatus, &ServiceStatus);
         return;        
      default:
         break;
    }  
    SetServiceStatus (hStatus, &ServiceStatus);
    return;
}
------------------------------------------------------------

The above  ControlHandler(DWORD) method
is registered using RegisterServiceCtrlHandler()

-SRK
0
 
PaulCaswellCommented:
Heres some code in a service I work with that stops itself. I didnt write it but it may be of help.

 //
//  FUNCTION: service_ctrl
//
//  PURPOSE: This function is called by the SCM whenever
//           ControlService() is called on this service.
//
//  PARAMETERS:
//    dwCtrlCode - type of control requested
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
VOID WINAPI service_ctrl(DWORD dwCtrlCode)
{
    // Handle the requested control code.
    //
    switch(dwCtrlCode)
    {
        // Stop the service.
        //
        // SERVICE_STOP_PENDING should be reported before
        // setting the Stop Event - hServerStopEvent - in
        // ServiceStop().  This avoids a race condition
        // which may result in a 1053 - The Service did not respond...
        // error.
        case SERVICE_CONTROL_STOP:
            ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
            ServiceStop();
            return;

        // Update the service status.
        //
        case SERVICE_CONTROL_INTERROGATE:
            break;

        // invalid control code
        //
        default:
            break;

    }

    ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}


//
//  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 (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(3, "SetServiceStatus failed.");
    }

    return fResult;
}


This is a more gentle approach because we hold a NetBios channel open while we are running and we have to wait 'till its closed before closing.

Paul
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now