Link to home
Start Free TrialLog in
Avatar of corduroy9
corduroy9

asked on

Windows XP Service error 1053

Hi I have a custom user definied windows 2000 service that WORKS.  The problem is when I ported it to Windows XP or Windows 2003 it no longer works?  What is the most likely issue with this?  If you need code I can paste some in but I'm assuming since it works in Windows 2000 the code is not an issue.
Avatar of Axter
Axter
Flag of United States of America image

Hi corduroy9,
What user are you connecting the service as?

If you're connecting as a specific user, make sure it's valid on the machine.

Also, does your service have any dependencies?

If so, make sure they're started before your serivce starts.

David Maisonave :-)
Cheers!
The error is

//
// MessageId: ERROR_SERVICE_REQUEST_TIMEOUT
//
// MessageText:
//
//  The service did not respond to the start or control request in a timely
//  fashion.
//
#define ERROR_SERVICE_REQUEST_TIMEOUT    1053L

Add logging code to your service's control handler routine to see what control requests are actually being sent and which ones are processed.
BTW, see also http://msdn.microsoft.com/library/en-us/dllproc/base/writing_a_control_handler_function.asp ("Writing a Control Handler Function") on control handlers in general.
Avatar of corduroy9
corduroy9

ASKER

I have no dependencies on these services....

I have a Control Handler routine.

BOOL WINAPI ControlHandler( DWORD dwCtrlType )
{
      BOOL RetVal = FALSE;

    switch( dwCtrlType )
    {
        case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to call shutdown
                  fnLog( L_CRITICAL, "CTRL_BREAK_EVENT - Detected",1,__FILE__,__LINE__);
                  RetVal = TRUE;
                  break;

        case CTRL_C_EVENT:
                  fnLog( L_CRITICAL, "CTRL_C_EVENT - Detected",1,__FILE__,__LINE__);
                  RetVal = TRUE;
            break;

        case CTRL_CLOSE_EVENT:
                  fnLog( L_CRITICAL, "CTRL_CLOSE_EVENT - Detected",1,__FILE__,__LINE__);
                  RetVal = TRUE;
            break;

            //------------------------------------------------------------
            // The "CTRL_LOGOFF_EVENT" is NOT trapped, because the program
            // should not brought off line when the user logs off.
            //------------------------------------------------------------
        case CTRL_SHUTDOWN_EVENT:
                  fnLog( L_CRITICAL, "CTRL_SHUTDOWN_EVENT - Detected",1,__FILE__,__LINE__);
                  RetVal = TRUE;
            break;
    }

      //----------------------------------------------------------------
      // Only shut down if one of the shut down conditions has been met.
      // The "CTRL_LOGOFF_EVENT" will cause this function to be called,
      // but this is NOT a shut down condition!!!!!!!
      //----------------------------------------------------------------
      if ( RetVal == TRUE )
      {
            sProgramExit = EXIT;      // set program exit flag
      }

    return RetVal;
}
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
should I change my code to reflect what is in the link you sent me?
What user are you connecting the service as?
>> I have no dependencies on these services....

Um, that is quite unrelated...
>> What user are you connecting the service as?

Um, that is quite unrelated also...

>> should I change my code to reflect what is in the link you sent me?

Yes, you definitely need to do that - NT and W2k might have tolerated not changing the status, XP apparently doesn't.
>>Um, that is quite unrelated also...

Why would that be unrelated?
>>Why would that be unrelated?

//
// MessageId: ERROR_SERVICE_REQUEST_TIMEOUT
//
// MessageText:
//
//  The service did not respond to the start or control request in a timely
//  fashion.
//
#define ERROR_SERVICE_REQUEST_TIMEOUT    1053L

Service control requests that time out have nothing to do with user accounts - either they're accepted your you get 'access denied' when opening the service handle.
From MSDN:
****************************************************************
A service is an application that can execute even when no user is logged on to the system. A service typically runs under a ***special user*** account named the LocalSystem account. Applications that run under the LocalSystem account have special privileges that give them a lot of power on the local computer. Under most circumstances, you do not want to give a user to this kind of power (it can be used to bypass system security).
****************************************************************

That's why I'm asking what user is the service connecting as.

If the service is being loaded under an account that does not have the required priviledges, then the service will fail.

continue....
corduroy9,
Can you restart your service after you loggon?

If you can restart it after you loggon, then it's probably a dependency issue.
>> From MSDN:
>>[...]
>>That's why I'm asking what user is the service connecting as.

And how's that related to a timeout? *puzzled*
>>And how's that related to a timeout? *puzzled*

Are you saying you've never seen a timeout when a program tries to acess something it doesn't have access to?

You're probably right, in that it's not the issue, but I think it would be unwise to rule it out without testing.
Ok well lets try to get back on track here.  I tried adding the Service Control Handler that jkr proposed and that did not work.  Any new ideas?
Well, have you added diagnostic output to see what control requests are passed in (as suggested earlier)?
Can you restart your service after you loggon?
unsubscribing due to lack of feedback.

Also just notice questioner's Grading history:
B B B B A C B B B B
I have the SVC Debug output as the example does, but my code does not output any information.  Well I can restart any services because I can't start them.
Secondly I give a lot of B's because I generally don't get the exact answer I need.
>>Well I can restart any services because I can't start them.

Can you go to Services ICON listed under control pannel or Admin Tools

Then select your service, and then click START?
>>but my code does not output any information

You could try to

VOID WINAPI MyServiceCtrlHandler (DWORD Opcode)
{
   DWORD status;
   char acOutput;

   wsprintf ( "CtrlHandler: Received CtrlCode %d\n", Opcode);

   OutputDebugString ( acOutput);

//...
}

Then, you'll see which control requests are handled without timeouts and which aren't.
Axter > Yes I can click Start, Then I get the error.  Then I can go back and do it again, and yet I'll still recieve that error.
>>Secondly I give a lot of B's because I generally don't get the exact answer I need.

1. That could be because you're not asking the right question
2. You're not providing enough information in your question
3. You're not providing feedback like in this question

The quality of the answer is highly dependant on the quality of feedback from the questioner.

Furthermore, in reviewing your questions, I don't see you giving the experts a chance to give you an A grade answer.

If you're not satisfied with the answer, it's up to you to provide that feedback to the experts.
jkr > I tried adding the outputdebugstring.  And still recieve no output.  Maybe the error is happening earlier in the code?  Or Maybe this is an XP Issue or something...
Stupit Q: Is your control handler registered correctly via 'RegisterServiceCtrlHandler()'? What is your startup code?
#if SERVICE
//----------------------------------------------------------------------
// main()
//
// This function calls StartServiceCtrlDispatcher to register the main
// service thread. When the API returns, the service has stopped, so
// the program will exit.
//
// Original MicroSoft sample "service.c" function.
//----------------------------------------------------------------------
VOID
main()
{
    SERVICE_TABLE_ENTRY dispatchTable[] = {
        { TEXT("SimpleService"), (LPSERVICE_MAIN_FUNCTION)service_main },
        { NULL, NULL }
    };
    if (!StartServiceCtrlDispatcher(dispatchTable)) {
        StopSimpleService("StartServiceCtrlDispatcher failed.");
    }

}

//----------------------------------------------------------------------
//
// service_main()
//
// This function takes care of actually starting the service, informing
// the service controller at each step along the way. After launching
// the worker thread (i.e. the "ModcaRoute" functionality), it waits on
// the event that the worker thread will signal at its termination.
//
// Original MicroSoft sample "service.c" function.
//----------------------------------------------------------------------
VOID
service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
    DWORD                   dwWait;
    PSECURITY_DESCRIPTOR    pSD;
    SECURITY_ATTRIBUTES     sa;
    // register our service control handler:
    //
    sshStatusHandle = RegisterServiceCtrlHandler(
                                    TEXT("SimpleService"),
                                    service_ctrl);
    if (!sshStatusHandle)
        goto cleanup;
    // SERVICE_STATUS members that don't change in example
    //
    ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    ssStatus.dwServiceSpecificExitCode = 0;

    // Report the status to Service Control Manager.
    //
    if (!ReportStatusToSCMgr(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        1,                     // checkpoint
        3000))                 // wait hint
        goto cleanup;

    // Create the event object. The control handler function signals
    // this event when it receives the "stop" control code.
    //
    hServDoneEvent = CreateEvent(
        NULL,    // no security attributes
        TRUE,    // manual reset event
        FALSE,   // not-signalled
        NULL);   // no name
    if (hServDoneEvent == (HANDLE)NULL)
        goto cleanup;
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        2,                     // checkpoint
        3000))                 // wait hint
        goto cleanup;
    // Create a security descriptor that allows anyone to write to the pipe...
    //
    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
                SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (pSD == NULL) {
        StopSimpleService("LocalAlloc pSD failed");
        return;
    }
    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
        StopSimpleService("InitializeSecurityDescriptor failed");
        LocalFree((HLOCAL)pSD);
        return;
    }
    // Add a NULL disc. ACL to the security descriptor.
    //
    if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE)) {
        StopSimpleService("SetSecurityDescriptorDacl failed");
        LocalFree((HLOCAL)pSD);
        return;
    }
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = TRUE;       // why not...

    // Start the thread that performs the work of the service.
    //
    threadHandle = (HANDLE)_beginthread(
                    worker_thread,
                    4096,       // stack size
                    NULL);      // argument to thread
    if (!threadHandle)
        goto cleanup;

    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr(
        SERVICE_RUNNING, // service state
        NO_ERROR,        // exit code
        0,               // checkpoint
        0))              // wait hint
        goto cleanup;

    // Wait indefinitely until hServDoneEvent is signaled.
    //
    dwWait = WaitForSingleObject(
        hServDoneEvent,  // event object
        INFINITE);       // wait indefinitely
cleanup:
    if (hServDoneEvent != NULL)
        CloseHandle(hServDoneEvent);

    // Try to report the stopped status to the service control manager.
    //
    if (sshStatusHandle != 0)
        (VOID)ReportStatusToSCMgr(
                            SERVICE_STOPPED,
                            dwGlobalErr,
                            0,
                            0);
    // When SERVICE MAIN FUNCTION returns in a single service
    // process, the StartServiceCtrlDispatcher function in
    // the main thread returns, terminating the process.
    //
    return;
}

//----------------------------------------------------------------------
// service_ctrl()
//
// This function is called by the Service Controller whenever someone
// calls ControlService in reference to our service.
//
// Original MicroSoft sample "service.c" function.
//----------------------------------------------------------------------
VOID WINAPI
service_ctrl(DWORD dwCtrlCode)
{
    DWORD  dwState = SERVICE_RUNNING;
    // Handle the requested control code.
    //
    switch(dwCtrlCode) {
        // Pause the service if it is running.
        //
        case SERVICE_CONTROL_PAUSE:
            if (ssStatus.dwCurrentState == SERVICE_RUNNING) {
                SuspendThread(threadHandle);
                dwState = SERVICE_PAUSED;
            }
            break;
        // Resume the paused service.
        //
        case SERVICE_CONTROL_CONTINUE:
            if (ssStatus.dwCurrentState == SERVICE_PAUSED) {
                ResumeThread(threadHandle);
                dwState = SERVICE_RUNNING;
            }
            break;
        // Stop the service.
        //
        case SERVICE_CONTROL_STOP:
            dwState = SERVICE_STOP_PENDING;
            // Report the status, specifying the checkpoint and waithint,
            //  before setting the termination event.
            //
            ReportStatusToSCMgr(
                    SERVICE_STOP_PENDING, // current state
                    NO_ERROR,             // exit code
                    1,                    // checkpoint
                    3000);                // waithint
            SetEvent(hServDoneEvent);
            return;
        // Update the service status.
        //
        case SERVICE_CONTROL_INTERROGATE:
            break;
        // invalid control code
        //
        default:
            break;
    }
    // Send a status response.
    //
    ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0);
}
#endif
I mean shouldn't really all this code work if it works in a Windows 2000/NT environment
Hmm, I canoot see any logging output in 'service_ctrl()', maybe that's why you're not seeing anything. If you added a different control handler, you should use it's name with 'RegisterServiceCtrlHandler()'
Well still nothing after I added the Debug code not sure why... I'm just using the sample code that microsoft gives.  You think I should try compling the code in Windows XP?
>>You think I should try compling the code in Windows XP?

You could try that, but I don't think that will make any difference. I'd just add more diagnostic output all over the code or try to debug it: http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b170738 ("Debugging a Windows NT Service") (in this article, you can use msdev.exe instead of windbg.exe)
You didn't answer to question what user account you are connecting as?
Is it LocalSystem account or a special user account?

If we assume that your service_main function was invoked, there are 8 possibilities the service may fail before reporting SERVICE_RUNNING to SCM (what theoretically could fail also), some of them related to the account you are starting the service with.

- RegisterServiceCtrlHandler
- ReportStatusToSCMgr(SERVICE_START_PENDING, ...)
- CreateEvent
- ReportStatusToSCMgr(SERVICE_START_PENDING, ...)
- pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
- if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
- if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE))
- threadHandle = (HANDLE)_beginthread(...)

I would suggest to use a log function like the following after each of these calls to make clear where your service fails.

#include <fstream>
using namespace std;

void log(const char* logfile, const char* psz)
{
     ofstream ofs(logfile, ios::out | ios::append);
     ofs << psz << endl;
     ofs.close();
}

Call the function like that at all relevant error returns:

service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
      log("c:/temp/service.log", "service_main start");
      ...

}

Regards, Alex
Just in case this hasn't been mentioned: Service control requests aren't related to user account issues. If there was an access right problem, the service handle (which is needed to send request) cannot be obtained in the 1st place. The error ERROR_SERVICE_REQUEST_TIMEOUT  is issued by the SCM if it encounters a timeout.
>>>> The error ERROR_SERVICE_REQUEST_TIMEOUT  is issued by the SCM if it encounters a timeout.

The error ERROR_SERVICE_REQUEST_TIMEOUT  is issued by the SCM if the service does not sende status SERVICE_RUNNING to SCM.

>>>> Service control requests aren't related to user account issues.

Of course some of the calls *before* sending SERVICE_RUNNING are at least not independend of he account the services is running on, e. g. a call to SetSecurityDescriptorDacl may fail if the account hasn't appropriate access rights.