Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1392
  • Last Modified:

Service Shutdown - WIN32

If I shutdown NT when my NT Service is running, my service does not receive SERVICE_CONTROL_SHUTDOWN signal even though it is definitely set with SERVICE_ACCEPT_SHUTDOWN. The consequence is that if somebody shuts down NT without stopping my Service, my Service does not clean up properly.
Any ideas.
0
ascot
Asked:
ascot
  • 3
  • 2
1 Solution
 
biyiadeniranCommented:
sould you give mor einfo pls
did you use visual basic to write the code.
waht does the line for SERVICE_CONTROL_SHUTDOWN and SERVICE_accept_SHUTDOWN look like
0
 
jhanceCommented:
IS the following a possible cause?

The SERVICE_CONTROL_SHUTDOWN control should only be processed by services that must absolutely clean up during shutdown, because there is an extremely limited time (about 20 seconds) available for service shutdown. After this time expires, system shutdown proceeds regardless of whether service shutdown is complete. If the service needs to take more time to shut down, it should send out STOP_PENDING status messages, along with a waithint, so that the service controller knows how long to wait before reporting to the system that service shutdown is complete. For example, the eventlog service needs to clear a dirty bit in the files that it maintains, and the server service needs to shut down so that network connections aren’t made when the system is in the shutdown state.
0
 
ascotAuthor Commented:
No, unfortunately the problem is worse than that because I am not even getting the SERVICE_CONTROL_SHUTDOWN signal.  All that I am trying to do in my shutdown code at the moment is write a message to a log file to indicate that I've had the signal.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jhanceCommented:
In that case, are you getting ANY Service Control Manager messages at all?  If not, then your service is not registering itself with SCM properly.  If it is getting some messages, are you sure that it's not hung or deadlocked for some reason by another service?  
0
 
ascotAuthor Commented:
Here are the Service Control handler functions, written in C.  I do get the Service Control Stop message OK.  When I shutdown NT I do not get the "Got SCM Control Code" message output in my log file.

BOOL SendStatusToSCM (      DWORD dwCurrentState,
                  DWORD dwWin32ExitCode,
                  DWORD dwServiceSpecificExitCode,
                  DWORD dwWaitHint)
{
      static DWORD dwCheckPoint = 1;
      BOOL success = TRUE;
      SERVICE_STATUS gserviceStatus;
       
      // Fill in all of the SERVICE_STATUS fields
      gserviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
      gserviceStatus.dwCurrentState = dwCurrentState;

      if (dwCurrentState == SERVICE_START_PENDING)
            gserviceStatus.dwControlsAccepted = 0;
      else
            gserviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;

      gserviceStatus.dwWin32ExitCode =      dwWin32ExitCode;
      
      gserviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;

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

      return (success);
}

VOID ServiceCtrlHandler (DWORD controlCode)
{
      DWORD  currentState = 0;
      BOOL success;

      LogDebug (__FILE__, __LINE__, "Got SCM Control Code %ld", controlCode);
      
      switch(controlCode)
      {
            case SERVICE_CONTROL_STOP:
                  LogDebug (__FILE__, __LINE__, "Got a SERVICE_CONTROL_STOP");
                  gbStopped = TRUE;
                  currentState = SERVICE_STOP_PENDING;
                  success = SendStatusToSCM(      SERVICE_STOP_PENDING,
                                          NO_ERROR,
                                          0,
                                          30000);
                  
                  SetEvent(terminateEvent);
                  return;

            case SERVICE_CONTROL_PAUSE:
                  // Should never get this
                  break;

            case SERVICE_CONTROL_CONTINUE:
                  // Should never get this
                  break;

            case SERVICE_CONTROL_INTERROGATE:
                  LogDebug (__FILE__, __LINE__, "Got a SERVICE_CONTROL_INTERROGATE");
                  // it will fall to bottom and send status
                  break;

            case SERVICE_CONTROL_SHUTDOWN:
                  gbStopped = TRUE;
                  currentState = SERVICE_STOP_PENDING;
                  LogDebug (__FILE__, __LINE__, "Got a SERVICE_CONTROL_SHUTDOWN");
                  SetEvent(terminateEvent);
                  return;

            default:
                   break;
      }
      SendStatusToSCM(      currentState,
                        NO_ERROR,
                        0,
                        0);
}

Here follows extract of my code to install the service :

install ()
{
      scm = OpenSCManager(      0,
                        0,
                        SC_MANAGER_ALL_ACCESS);
      
      if (!scm)
            ErrorHandler ("OpenSCmanager failed");

      // Install the new service
      newService = CreateService(      scm,
                              pszServiceName,
                              pszDisplayName,
                              SERVICE_ALL_ACCESS,
                              SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
                              SERVICE_AUTO_START,
                              SERVICE_ERROR_NORMAL,
                              CommandLine,
                              0,
                              0,
                              "RPCSS\0RPCLOCATOR\0\0",
                               0,
                              0);
}

0
 
jhanceCommented:
In the examnple below:

>case SERVICE_CONTROL_SHUTDOWN:
>gbStopped = TRUE;
>currentState = SERVICE_STOP_PENDING;
>LogDebug (__FILE__, __LINE__, "Got a SERVICE_CONTROL_SHUTDOWN");
>SetEvent(terminateEvent);
>return;

Is it possible that the service is terminated by NT before the LogDebug operation completes?  LogDebug is your function, how does it ensure that any pending data is flushed before returning?
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

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