HRESULT Service_Monitor::MonitoringService(LPCTSTR pServiceName, DWORD dwStatus, HANDLE hStopEvent)
{
    HRESULT   hr = S_OK;
    DWORD     dwError = ERROR_SUCCESS;
    DWORD     dwWaitResult;
    SC_HANDLE hService;
    SERVICE_NOTIFY sNotify;

    hr = GetServiceHandle(pServiceName, &hService);
    if(FAILED(hr))
    {
        goto Finished;
    }

    sNotify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
    sNotify.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)NotifyCallBack;
    sNotify.pszServiceNames = (LPWSTR) pServiceName;
    sNotify.pContext = hStopEvent;

    dwError = NotifyServiceStatusChange(hService, dwStatus, &sNotify);
    if (dwError != ERROR_SUCCESS)
    {
        hr = HRESULT_FROM_WIN32(dwError);
        _tprintf(L"\nERROR: fail to register status change callback [%x]\n", hr);
        goto Finished;
    }

    dwWaitResult = WaitForSingleObjectEx(hStopEvent, INFINITE, TRUE);
    switch (dwWaitResult)
    {
        // Event object was signaled
    case WAIT_OBJECT_0:
    case WAIT_IO_COMPLETION:
        break;

        // An error occurred
    default:
        hr = HRESULT_FROM_WIN32(GetLastError());
        _tprintf(L"\nERROR: Monitoring service '%s' wait error [%x]\n", pServiceName, hr);
    }

Finished:
    if (hService != NULL)
    {
        CloseServiceHandle(hService);
    }
    return hr;
}
bool
Module::StopService(_In_ SC_HANDLE serviceHandle)
{
    // Signal service to stop.
    SERVICE_STATUS serviceStatus;
    BOOL controlServiceResult = ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus);
    if (!controlServiceResult)
    {
        DWORD lastError = GetLastError();
        if (lastError != ERROR_SERVICE_NOT_ACTIVE &&
            lastError != ERROR_SERVICE_CANNOT_ACCEPT_CTRL &&
            serviceStatus.dwCurrentState != SERVICE_START_PENDING)
        {
            LOG_COMMENT(L"Failed to send service stop command.");
            return false;
        }
    }

    auto serviceStoppedCallback = [] (void* /*context*/)
    {
    };

    // Register for service stopped event.
    SERVICE_NOTIFY serviceNotifyData = {};
    serviceNotifyData.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
    serviceNotifyData.pfnNotifyCallback = serviceStoppedCallback;

    DWORD registerServiceEventResult = NotifyServiceStatusChange(serviceHandle, SERVICE_NOTIFY_STOPPED, &serviceNotifyData);
    if (registerServiceEventResult != ERROR_SUCCESS)
    {
        LOG_COMMENT(L"Failed to subscribe to service stopped event.");
        return false;
    }

    // Wait for event.
    DWORD sleepResult = SleepEx(/*time(ms)*/ 30000, /*APC*/ TRUE);
    if (sleepResult == 0)
    {
        LOG_COMMENT(L"Service took too long to stop.");
        return false;
    }

    // Cleanup.
    LOG_COMMENT(L"Service stopped.");
    return true;
}
示例#3
0
文件: main.c 项目: spthaolt/winfuse
int main(int ac, _TCHAR** av)
{
  int error;
  struct _THREAD_PARAM InputThreadParam;
  HANDLE InputEventHandle;
  HANDLE InputThreadHandle;
  SC_HANDLE ManagerHandle;
  SC_HANDLE ServiceHandle;
  _TCHAR* DriverPath;
  _TCHAR* ServiceName;
  HKEY ServiceKey;
  void* Cmdline;
  DWORD CmdlineLength;
  SERVICE_STATUS ServiceStatus;
  BOOLEAN isDone;
  DWORD res;
  _TCHAR KeyName[1024];

  if (ac == 1)
    {
      printf("%s: <driver> <avs>\n", av[0]);
      return -1;
    }

  DriverPath = GetFullPath(av[1]);
  if (DriverPath == NULL)
    {
      printf("GetFullPath() == NULL\n");
      return -1;
    }

  ServiceName = GetServiceName(DriverPath);
  if (ServiceName == NULL)
    {
      printf("GetServiceName() == NULL\n");
      return -1;
    }

  Cmdline = AvToMultiRegSz(av + 2, &CmdlineLength);
  if (Cmdline == NULL)
    {
      printf("AvToMultiRegSz() == NULL\n");
      return -1;
    }

  error = -1;

  InputEventHandle = NULL;
  InputThreadHandle = NULL;
  ServiceKey = NULL;
  ManagerHandle = NULL;
  ServiceHandle = NULL;

  ManagerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if (ManagerHandle == NULL)
    {
      printf("OpenSCManager() == %u\n", GetLastError());
      goto Cleanup;
    }

  /* remove the serice if already exist
   */

  ServiceHandle = OpenService(ManagerHandle,
			      ServiceName,
			      SC_MANAGER_ALL_ACCESS);
  if (ServiceHandle != NULL)
    {
      if (DeleteService(ServiceHandle) == FALSE)
	{
	  printf("DeleteService() == %u\n", GetLastError());
	  goto Cleanup;
	}

      ServiceHandle = NULL;
    }

  /* create the service
   */

  ServiceHandle = CreateService(ManagerHandle,
				ServiceName,
				ServiceName,
				SC_MANAGER_ALL_ACCESS,
				SERVICE_KERNEL_DRIVER,
				SERVICE_DEMAND_START,
				SERVICE_ERROR_IGNORE,
				DriverPath,
				NULL,
				NULL,
				NULL,
				NULL,
				NULL);
  if (ServiceHandle == NULL)
    {
      printf("CreateService() == %u\n", GetLastError());
      goto Cleanup;
    }

  /* set registry
   */

  _tcscpy(KeyName, _T("SYSTEM\\CurrentControlSet\\Services\\"));
  _tcscat(KeyName, ServiceName);

  if (RegOpenKey(HKEY_LOCAL_MACHINE,
		 KeyName,
		 &ServiceKey) != ERROR_SUCCESS)
    {
      printf("RegOpenKey() == %u\n", GetLastError());
      goto Cleanup;
    }

  if (RegSetValueEx(ServiceKey,
		    _T("Cmdline"),
		    0,
		    REG_MULTI_SZ,
		    Cmdline,
		    CmdlineLength) != ERROR_SUCCESS)
    {
      printf("RegSetKeyValue() == %u\n", GetLastError());
      goto Cleanup;
    }

  /* input thread
   */

  InputEventHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
  if (InputEventHandle == NULL)
    {
      printf("CreateEvent() == %u\n", GetLastError());
      goto Cleanup;
    }

  InputThreadParam.InputEventHandle = InputEventHandle;
  InputThreadHandle = CreateThread(NULL,
				   0,
				   InputThreadRoutine,
				   &InputThreadParam,
				   0,
				   NULL);
  if (InputThreadHandle == NULL)
    {
      printf("CreateThread() == %u\n", GetLastError());
      goto Cleanup;
    }

  /* start the service
   */

  if (StartService(ServiceHandle, 0, NULL) == FALSE)
    {
      printf("StartService() == %u\n", GetLastError());
      goto Cleanup;
    }

#if 0 /* VISTA */
  {
    EventHandle = CreateHandle();
    if (EventHandle)
      {
	printf("CreateEvent() == %u\n", GetLastError());
	goto Cleanup;
      }

    memset(&ServiceNotify, 0, sizeof(ServiceNotify));
    ServiceNotify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
    ServiceNotify.pfnNotifyCallback = onServiceChange;
    ServiceNotify.pContext = &EventHandle;

    NotifyServiceStatusChange(ServiceHandle,
			      SERVICE_NOTIFY_STOPPED,
			      &ServiceNotify);

    WaitForSingleObject(EventHandle, INFINITE);
  }
#else /* ! VISTA */
  {

    /* wait for the service to be stopped
     */

    isDone = FALSE;

    while (isDone == FALSE)
      {
	res = WaitForSingleObject(InputEventHandle, 1000);

	if (res == WAIT_OBJECT_0)
	  ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus);

	if (QueryServiceStatus(ServiceHandle,
			       &ServiceStatus) == FALSE)
	  {
	    printf("QueryServiceStatus() == %u\n", GetLastError());
	    ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus);
	    goto Cleanup;
	  }

	if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
	  {
	    if (ServiceStatus.dwWin32ExitCode == ERROR_SERVICE_SPECIFIC_ERROR)
	      error = ServiceStatus.dwServiceSpecificExitCode;
	    else
	      error = ServiceStatus.dwWin32ExitCode;

	    isDone = TRUE;
	  }
      }
  }
#endif /* VISTA */

  /* success
   */
  
 Cleanup:

  if (InputThreadHandle != NULL)
    {
      TerminateThread(InputThreadHandle, 0);
      CloseHandle(InputThreadHandle);
    }
  
  if (InputEventHandle != NULL)
    CloseHandle(InputEventHandle);

  if (Cmdline != NULL)
    free(Cmdline);

  if (ServiceKey != NULL)
    RegCloseKey(ServiceKey);

  if (ServiceHandle != NULL)
    {
      if (DeleteService(ServiceHandle) == FALSE)
	printf("DeleteService() == %u\n", GetLastError());
      CloseServiceHandle(ServiceHandle);
    }

  if (ManagerHandle != NULL)
    CloseServiceHandle(ManagerHandle);

  return error;
}