//添加服务主线程函数和控制函数
void WINAPI wx_service::ServiceMain(DWORD   dwArgc,   LPTSTR   *lpszArgv)
{
	log( "ServiceMain : ServeiceName: %s  args: %s ", szServiceName , lpszArgv);
	//注册服务控制
	hServiceStatus = RegisterServiceCtrlHandler( szServiceName, &ServiceHandle);
	if (hServiceStatus == NULL)
	{
		log( "ServiceHandle not installed" );
		LogEvent(("ServiceHandle not installed"));
		return;
	}
	log( "ServiceHandle installed & SetServiceStatus SERVICE_START_PENDING " );
	status.dwWaitHint = 10;
	status.dwCurrentState = SERVICE_START_PENDING;
	status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;//这个要使用,否则你不能控制
	SetServiceStatus(hServiceStatus, &status);

	status.dwWin32ExitCode = S_OK;
	status.dwCheckPoint = 0;
	status.dwWaitHint = 0;
	status.dwCurrentState = SERVICE_RUNNING;
	log( "SetServiceStatus SERVICE_RUNNING" );
	SetServiceStatus( hServiceStatus, &status);

	log( "RUNNING" );
	//运行监控
	dwThreadID   =   GetCurrentThreadId()   ;   
	Run();
	log( "Run() returned" );
	 
	status.dwCurrentState = SERVICE_STOPPED;
	SetServiceStatus(hServiceStatus, &status);
	LogEvent(("Service stopped"));
	 

}
示例#2
0
void WINAPI ServiceMain(DWORD dwNumServicesArgs, LPSTR *lpServiceArgVectors)
{
    /* initialise service status */
    serviceStatus.dwServiceType = SERVICE_WIN32;
    serviceStatus.dwCurrentState = SERVICE_STOPPED;
    serviceStatus.dwControlsAccepted = 0;
    serviceStatus.dwWin32ExitCode = NO_ERROR;
    serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
    serviceStatus.dwCheckPoint = 0;
    serviceStatus.dwWaitHint = 0;

    serviceStatusHandle = RegisterServiceCtrlHandler(PACKAGE_NAME, ServiceControlHandler);

    if(serviceStatusHandle) {
        /* set the service curent status as starting */
        serviceStatus.dwCurrentState = SERVICE_START_PENDING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);

        /* set the service curent status as running and accepting shutdown */
        serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
        serviceStatus.dwCurrentState = SERVICE_RUNNING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);

        /* execute the main code */
        if(runServer) runServer();

        /* set the service curent status as stopping */
        serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);

        /* set the service curent status as stopped and not accepting shutdown*/
        serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
        serviceStatus.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
    }
}
示例#3
0
/** void WINAPI OssecServiceStart (DWORD argc, LPTSTR *argv)
 * Starts OSSEC service
 */
void WINAPI OssecServiceStart (DWORD argc, LPTSTR *argv)
{
    ossecServiceStatus.dwServiceType            = SERVICE_WIN32;
    ossecServiceStatus.dwCurrentState           = SERVICE_START_PENDING;
    ossecServiceStatus.dwControlsAccepted       = SERVICE_ACCEPT_STOP;
    ossecServiceStatus.dwWin32ExitCode          = 0;
    ossecServiceStatus.dwServiceSpecificExitCode= 0;
    ossecServiceStatus.dwCheckPoint             = 0;
    ossecServiceStatus.dwWaitHint               = 0;

    ossecServiceStatusHandle = 
        RegisterServiceCtrlHandler(g_lpszServiceName, 
                                   OssecServiceCtrlHandler);

    if (ossecServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
    {
        merror("%s: RegisterServiceCtrlHandler failed.", ARGV0);
        return;
    }

    ossecServiceStatus.dwCurrentState = SERVICE_RUNNING;
    ossecServiceStatus.dwCheckPoint = 0;
    ossecServiceStatus.dwWaitHint = 0;

    if (!SetServiceStatus(ossecServiceStatusHandle, &ossecServiceStatus))
    {
        merror("%s: SetServiceStatus error.", ARGV0);
        return;
    }


    #ifdef OSSECHIDS
    /* Starting process */
    local_start();
    #endif
}
示例#4
0
VOID
wisvc_KublServiceStart (DWORD argc, LPTSTR * argv)
{
  DWORD status;
  DWORD specificError = 0;
  char *service_name = find_service_name_from (argv);
  char *cutpnt;

/* First chdir to the same directory where the executable is
   (got from argv[0] of original main arguments), so that further
   error messages printed with wisvc_err_printf (which calls log_error
   in turn) will be appended to wi.err file in more appropriate
   place than \WINNT\SYSTEM32 directory.
 */
  if (wisvc_Main_G_argv && wisvc_Main_G_argv[0] &&
      (NULL != (cutpnt = strrchr (wisvc_Main_G_argv[0], '\\'))))
    {				/* Search the last backslash. */
      ptrlong len;
      char *work_dir;

      len = (cutpnt - wisvc_Main_G_argv[0]);
      if (NULL == (work_dir = ((char *) malloc (len + 1))))
	{
	  exit (7);		/* Failed beyond all reason, best to exit. */
	}
      else
	{
	  strncpy (work_dir, wisvc_Main_G_argv[0], len);	/* Leave backslash there */
	  work_dir[len] = '\0';
	}

      if (chdir (work_dir))	/* Is not zero, i.e. -1, an error. */
	{			/* However, we do not exit yet. */
/*        DWORD erhe = GetLastError(); */

	  wisvc_err_printf ("%s: Cannot chdir to \"%s\" because: %s",
			    argv[0], work_dir, strerror (errno));
	}
      free (work_dir);
    }

  wisvc_KublServiceStatus.dwServiceType = SERVICE_WIN32;
  wisvc_KublServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  wisvc_KublServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  /* | SERVICE_ACCEPT_PAUSE_CONTINUE; (Not for wisvc_Kubl) */
  wisvc_KublServiceStatus.dwWin32ExitCode = 0;
  wisvc_KublServiceStatus.dwServiceSpecificExitCode = 0;
  wisvc_KublServiceStatus.dwCheckPoint = 0;
  wisvc_KublServiceStatus.dwWaitHint = 2;

  wisvc_KublServiceStatusHandle =
    RegisterServiceCtrlHandler (TEXT (service_name),
		       ((LPHANDLER_FUNCTION) wisvc_KublServiceCtrlHandler));

  if (wisvc_KublServiceStatusHandle == (SERVICE_STATUS_HANDLE) 0)
    {
      wisvc_err_printf ("%s: (%s) RegisterServiceCtrlHandler failed %ld\n",
			wisvc_Main_G_argv[0], service_name, GetLastError ());
      return;
    }

  /* Now we are calling kubl_main second time. */
  status = kubl_main (argc, argv, 1, &specificError);

  if (status != NO_ERROR)	/* Handle error condition */
    {
      wisvc_KublServiceStatus.dwCurrentState = SERVICE_STOPPED;
      wisvc_KublServiceStatus.dwCheckPoint = 0;
      wisvc_KublServiceStatus.dwWaitHint = 0;
      wisvc_KublServiceStatus.dwWin32ExitCode = status;
      wisvc_KublServiceStatus.dwServiceSpecificExitCode = specificError;

      SetServiceStatus (wisvc_KublServiceStatusHandle, &wisvc_KublServiceStatus);
      return;
    }

  wisvc_send_service_running_status ();


  /* This is where the service either does few checkpoints now and then
     or does nothing: */
    main_the_rest ();		/* In chil.c */

  return;
}
示例#5
0
int
WIN32_Subsystem_Init(int *argc, char ***argv)
{
    WIN32_OS_version = GetOSVersion();
    if ((WIN32_OS_version == _WIN_OS_UNKNOWN) || (WIN32_OS_version == _WIN_OS_WIN32S))
        return 1;
    if (atexit(WIN32_Exit) != 0)
        return 1;
#if USE_WIN32_SERVICE
    if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
        char path[512];
        HKEY hndKey;
        if (signal(SIGABRT, WIN32_Abort) == SIG_ERR)
            return 1;
        /* Register the service Handler function */
        svcHandle = RegisterServiceCtrlHandler(WIN32_Service_name, WIN32_svcHandler);
        if (svcHandle == 0)
            return 1;
        /* Set Process work dir to directory cointaining squid.exe */
        GetModuleFileName(NULL, path, 512);
        WIN32_module_name = xstrdup(path);
        path[strlen(path) - 10] = '\0';
        if (SetCurrentDirectory(path) == 0)
            return 1;
        safe_free(ConfigFile);
        /* get config file from Windows Registry */
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE, &hndKey) == ERROR_SUCCESS) {
            DWORD Type = 0;
            DWORD Size = 0;
            LONG Result;
            Result = RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size);
            if (Result == ERROR_SUCCESS && Size) {
                ConfigFile = xmalloc(Size);
                RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, ConfigFile, &Size);
            } else
                ConfigFile = xstrdup(DefaultConfigFile);
            Size = 0;
            Type = 0;
            Result = RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size);
            if (Result == ERROR_SUCCESS && Size) {
                WIN32_Service_Command_Line = xmalloc(Size);
                RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, WIN32_Service_Command_Line, &Size);
            } else
                WIN32_Service_Command_Line = xstrdup("");
            RegCloseKey(hndKey);
        } else {
            ConfigFile = xstrdup(DefaultConfigFile);
            WIN32_Service_Command_Line = xstrdup("");
        }
        WIN32_build_argv(WIN32_Service_Command_Line);
        *argc = WIN32_argc;
        *argv = WIN32_argv;
        /* Set Service Status to SERVICE_START_PENDING */
        svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        svcStatus.dwCurrentState = SERVICE_START_PENDING;
        svcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
        svcStatus.dwWin32ExitCode = 0;
        svcStatus.dwServiceSpecificExitCode = 0;
        svcStatus.dwCheckPoint = 0;
        svcStatus.dwWaitHint = 10000;
        SetServiceStatus(svcHandle, &svcStatus);
#ifdef _SQUID_MSWIN_
        _setmaxstdio(Squid_MaxFD);
#endif
    }
#endif
#ifdef _SQUID_MSWIN_
    if (Win32SockInit() < 0)
        return 1;
#endif
    return 0;
}
示例#6
0
文件: daemon.c 项目: marayl/aug
static void WINAPI
service_(DWORD argc, char** argv)
{
    /* Arguments are unused: these are specified as the "start parameters" in
       the Service Control Manager. */

    /* Service thread. */

    const char* sname;
    aug_bool daemon = AUG_TRUE;
    char home[AUG_PATH_MAX + 1];

	/* DebugBreak(); */

    /* Ensure writes performed on main thread are visible. */

    aug_rmb();

    if (!aug_inittlx()) {
        fprintf(stderr, "aug_inittlx() failed\n");
        return;
    }

    if (!(sname = aug_getservopt(AUG_OPTSHORTNAME))) {
        aug_setctxerror(aug_tlx, __FILE__, __LINE__, "aug", AUG_EINVAL,
                        AUG_MSG("option 'AUG_OPTSHORTNAME' not set"));
        aug_perrinfo(aug_tlx, "getservopt() failed", NULL);
        goto done;
    }

    /* Start console if interactive.  The console is opened before
       aug_readservconf() is called to prevent any log files from begin
       opened. */

    if (createconsole_(sname))
        daemon = AUG_FALSE;

    /* Install daemon logger prior to opening log file. */

    aug_setdaemonlog(aug_tlx);

    /* Fallback to tmp. */

    if (!aug_gethome(home, sizeof(home))
        && !aug_gettmp(home, sizeof(home))) {
        aug_ctxerror(aug_tlx, "failed to determine home directory");
        goto done;
    }

    /* Move away from system32. */

    if (!SetCurrentDirectory(home)) {
        aug_setwin32error(aug_tlx, __FILE__, __LINE__, GetLastError());
        aug_perrinfo(aug_tlx, "SetCurrentDirectory() failed", NULL);
        goto done;
    }

    if (AUG_CMDDEFAULT != options_.command_) {

        /* Commands other than AUG_CMDDEFAULT are invalid in this context. */

        aug_setctxerror(aug_tlx, __FILE__, __LINE__, "aug", AUG_EINVAL,
                        AUG_MSG("unexpected command value"));
        aug_perrinfo(aug_tlx, "invalid options", NULL);
        goto done;
    }

    if (aug_readservconf(AUG_CONFFILE(&options_), AUG_FALSE, daemon) < 0) {
        aug_perrinfo(aug_tlx, "aug_readservconf() failed", NULL);
        goto done;
    }

    if (!(ssh_ = RegisterServiceCtrlHandler(sname, handler_))) {

        aug_setwin32error(aug_tlx, __FILE__, __LINE__, GetLastError());
        aug_perrinfo(aug_tlx, "RegisterServiceCtrlHandler() failed", NULL);
        goto done;
    }

    setstatus_(SERVICE_START_PENDING);

    if (aug_initserv_BIN() < 0) {

        aug_perrinfo(aug_tlx, "aug_initserv_BIN() failed", NULL);
        setstatus_(SERVICE_STOPPED);
        goto done;
    }

    aug_ctxnotice(aug_tlx, "daemon started");
    setstatus_(SERVICE_RUNNING);

    if (aug_runserv() < 0)
        aug_perrinfo(aug_tlx, "aug_runserv() failed", NULL);

    aug_ctxnotice(aug_tlx, "daemon stopped");
    setstatus_(SERVICE_STOPPED);

    /* This function will be called on the Service Manager's thread.  Given
       that aug_initserv_BIN() and aug_runserv() have been called on this
       thread, aug_termserv() is also called from this thread and not the main
       thread. */

    aug_termserv();

 done:

    /* Flush pending writes to main memory. */

    aug_wmb();
    aug_term();
    if (!daemon)
        FreeConsole();
}
示例#7
0
文件: main.c 项目: 340211173/hf-2011
VOID WINAPI
service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
	HKEY hkey = NULL;
	char *config = NULL;
	DWORD type, config_size, status;

	// register our service control handler:
	//
	sshStatusHandle = RegisterServiceCtrlHandler("tdifw", service_ctrl);
	if (sshStatusHandle == 0) {
		winerr("install_service: RegisterServiceCtrlHandler");
		goto cleanup;
	}

	// 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
		goto cleanup;

	/* get config name from registry */

	if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CONFIG_SUBKEY, 0, KEY_QUERY_VALUE,
		&hkey)) != ERROR_SUCCESS) {
		SetLastError(status);
		winerr("RegOpenKeyEx");
		goto cleanup;
	}

	if ((status = RegQueryValueEx(hkey, "config", 0, &type, NULL, &config_size)) != ERROR_SUCCESS) {
		SetLastError(status);
		winerr("RegOpenKeyEx");
		goto cleanup;
	}

	if (type != REG_SZ) {
		error("Invalid type for config value in registry");
		SetLastError(ERROR_INVALID_DATA);
		goto cleanup;
	}

	config = (char *)malloc(config_size);
	if (config == NULL) {
		liberr("malloc");
		goto cleanup;
	}

	if ((status = RegQueryValueEx(hkey, "config", 0, NULL, config, &config_size)) != ERROR_SUCCESS) {
		SetLastError(status);
		winerr("RegOpenKeyEx");
		goto cleanup;
	}

	if (start(config)) {

		// start success

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

		wait();

		SetLastError(0);
	}
	
cleanup:

	// try to report the stopped status to the service control manager.
	//
	if (sshStatusHandle != 0)
		ReportStatusToSCMgr(SERVICE_STOPPED, GetLastError(), 0);

	if (hkey != NULL)
		RegCloseKey(hkey);
	free(config);
}
示例#8
0
文件: xrdpwin.c 项目: AsherBond/xrdp
VOID WINAPI
MyServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
    WSADATA w;
    char text[256];
    int pid;
    //HANDLE event_han;
    //  int fd;
    //  char text[256];

    //  fd = g_file_open("c:\\temp\\xrdp\\log.txt");
    //  g_file_write(fd, "hi\r\n", 4);
    //event_han = RegisterEventSource(0, "xrdp");
    //log_event(event_han, "hi xrdp log");
    g_threadid = tc_get_threadid();
    g_set_current_dir("c:\\temp\\xrdp");
    g_listen = 0;
    WSAStartup(2, &w);
    g_sync_mutex = tc_mutex_create();
    g_sync1_mutex = tc_mutex_create();
    pid = g_getpid();
    g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
    g_term_event = g_create_wait_obj(text);
    g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
    g_sync_event = g_create_wait_obj(text);
    g_memset(&g_service_status, 0, sizeof(SERVICE_STATUS));
    g_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_service_status.dwCurrentState = SERVICE_RUNNING;
    g_service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE |
                                          SERVICE_ACCEPT_STOP |
                                          SERVICE_ACCEPT_SHUTDOWN;
    g_service_status.dwWin32ExitCode = NO_ERROR;
    g_service_status.dwServiceSpecificExitCode = 0;
    g_service_status.dwCheckPoint = 0;
    g_service_status.dwWaitHint = 0;
    //  g_sprintf(text, "calling RegisterServiceCtrlHandler\r\n");
    //  g_file_write(fd, text, g_strlen(text));
    g_ssh = RegisterServiceCtrlHandler("xrdp", MyHandler);

    if (g_ssh != 0)
    {
        //    g_sprintf(text, "ok\r\n");
        //    g_file_write(fd, text, g_strlen(text));
        SetServiceStatus(g_ssh, &g_service_status);
        g_listen = xrdp_listen_create();
        xrdp_listen_main_loop(g_listen);
        g_sleep(100);
        g_service_status.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(g_ssh, &g_service_status);
    }
    else
    {
        //g_sprintf(text, "RegisterServiceCtrlHandler failed\r\n");
        //g_file_write(fd, text, g_strlen(text));
    }

    xrdp_listen_delete(g_listen);
    tc_mutex_delete(g_sync_mutex);
    tc_mutex_delete(g_sync1_mutex);
    g_destroy_wait_obj(g_term_event);
    g_destroy_wait_obj(g_sync_event);
    WSACleanup();
    //CloseHandle(event_han);
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
    DWORD Status = E_FAIL;

    // Register our service control handler with the SCM
    g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);

    if (g_StatusHandle == NULL)
    {
        goto EXIT;
    }

    // Tell the service controller we are starting
    ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
    g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwServiceSpecificExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;

    if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T(
            "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

    /*
    * Perform tasks necessary to start the service here
    */
    startup_sockets_mechanism();


    // Create a service stop event to wait on later
    g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (g_ServiceStopEvent == NULL)
    {
        // Error creating event
        // Tell service controller we are stopped and exit
        g_ServiceStatus.dwControlsAccepted = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwWin32ExitCode = GetLastError();
        g_ServiceStatus.dwCheckPoint = 1;

        if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
        {
            OutputDebugString(_T(
                "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        }
        goto EXIT;
    }

    // Tell the service controller we are started
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;

    if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T(
            "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

    // Start a thread that will perform the main task of the service
    HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

    // Wait until our worker thread exits signaling that the service needs to stop
    WaitForSingleObject(hThread, INFINITE);


    
    /*
    * Perform any cleanup tasks
    */
    cleanup_sockets_mechanism();

    CloseHandle(g_ServiceStopEvent);

    // Tell the service controller we are stopped
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 3;

    if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T(
            "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

EXIT:
    return;
}
示例#10
0
void WINAPI CNTL_main_thread( DWORD /*argc*/, char* /*argv*/[])
{
/**************************************
 *
 *	C N T L _ m a i n _ t h r e a d
 *
 **************************************
 *
 * Functional description
 *
 **************************************/
	service_handle = RegisterServiceCtrlHandler(service_name->c_str(), control_thread);
	if (!service_handle)
		return;

	// start everything, and wait here for ever, or at
	// least until we get the stop event indicating that
	// the service is stoping.

	bool failure = true;
	DWORD temp = 0;
	if (report_status(SERVICE_START_PENDING, NO_ERROR, 1, 3000) &&
		(stop_event_handle = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL &&
		report_status(SERVICE_START_PENDING, NO_ERROR, 2, 3000))
	{
		try
		{
			Thread::start(main_handler, NULL, THREAD_medium);
			if (report_status(SERVICE_RUNNING, NO_ERROR, 0, 0))
			{
				failure = false;
				temp = WaitForSingleObject(stop_event_handle, INFINITE);
			}
		}
		catch (const Firebird::Exception& ex)
		{
			iscLogException("CNTL: cannot start service handler thread", ex);
		}
	}

	DWORD last_error = 0;
	if (failure || temp == WAIT_FAILED)
		last_error = GetLastError();

	if (stop_event_handle)
		CloseHandle(stop_event_handle);

	// Once we are stopped, we will tell the server to
	// do the same.  We could not do this in the control_thread
	// since the Services Control Manager is single threaded,
	// and thus can only process one request at the time.
	SERVICE_STATUS status_info;
	SC_HANDLE hScManager = 0, hService = 0;
	hScManager = OpenSCManager(NULL, NULL, GENERIC_READ);
	hService = OpenService(hScManager, remote_name->c_str(), GENERIC_READ | GENERIC_EXECUTE);
	ControlService(hService, SERVICE_CONTROL_STOP, &status_info);
	CloseServiceHandle(hScManager);
	CloseServiceHandle(hService);

	report_status(SERVICE_STOPPED, last_error, 0, 0);
}
示例#11
0
void CALLBACK ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
	TCHAR szTmp[8192];
	char szTmpA[8192];
	TCHAR szTmp2[8192];
	char szAuthServer[32];
	DWORD dwTmp,dwType;
	HKEY hk;
	int seq=1,err;
	LPCSTR szNode;
	addrinfo *pAddrInfo;

	if(dwArgc!=999)
	{
		if (!(g_hService = RegisterServiceCtrlHandler(SERVICE_NAME,ServiceHandler))) { ReportError(TRUE,"Unable to start "SERVICE_NAMEA" - RegisterServiceCtrlHandler failed"); return; }
		NotifySCM(SERVICE_START_PENDING, 0, seq++);
	}
	else
	{
		g_bTestMode=TRUE;
		printf(SERVICE_NAMEA" " CVSNT_PRODUCTVERSION_STRING " ("__DATE__") starting in test mode.\n");
	}

	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),NULL,KEY_QUERY_VALUE,&hk))
	{ 
		ReportError(TRUE,"Unable to start "SERVICE_NAMEA" - Couldn't open environment key"); 
		if(!g_bTestMode)
			NotifySCM(SERVICE_STOPPED,0,0);
		return;
	}

	dwTmp=sizeof(szTmp);
	if(RegQueryValueEx(hk,_T("PATH"),NULL,&dwType,(BYTE*)szTmp,&dwTmp))
	{
		ReportError(TRUE,"Unable to start "SERVICE_NAMEA" - PATH environment variable not defined in system environment");
		if(!g_bTestMode)
			NotifySCM(SERVICE_STOPPED,0,0);
		return;
	}
	ExpandEnvironmentStrings(szTmp,szTmp2,sizeof(szTmp));
	SetEnvironmentVariable(_T("PATH"),szTmp2);

	RegCloseKey(hk);

	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\CVS\\Pserver"),NULL,KEY_QUERY_VALUE,&hk))
	{
		ReportError(TRUE,"Unable to start "SERVICE_NAMEA" - Couldn't open HKLM\\Software\\CVS\\Pserver key");
		if(!g_bTestMode)
			NotifySCM(SERVICE_STOPPED,0,0);
		return;
	}

	dwTmp=sizeof(szTmp);
	if(RegQueryValueEx(hk,_T("TempDir"),NULL,&dwType,(LPBYTE)szTmp,&dwTmp) &&
	   SHRegGetUSValue(_T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),_T("TEMP"),NULL,(LPVOID)szTmp,&dwTmp,TRUE,NULL,0) &&
	   !GetEnvironmentVariable(_T("TEMP"),(LPTSTR)szTmp,sizeof(szTmp)) &&
	   !GetEnvironmentVariable(_T("TMP"),(LPTSTR)szTmp,sizeof(szTmp)))
	{
		_tcscpy(szTmp,_T("C:\\"));
	}

	SetEnvironmentVariable(_T("TEMP"),szTmp);
	SetEnvironmentVariable(_T("TMP"),szTmp);
	if(g_bTestMode)
		_tprintf(_T("TEMP/TMP currently set to %s\n"),szTmp);

	dwTmp=sizeof(DWORD);
	if(!RegQueryValueEx(hk,_T("PServerPort"),NULL,&dwType,(BYTE*)szTmp,&dwTmp))
	{
		authserver_port=*(DWORD*)szTmp;
	}
	itoa(authserver_port,szAuthServer,10);

// Initialisation
    WSADATA data;

    if(WSAStartup (MAKEWORD (1, 1), &data))
	{
		ReportError(TRUE,"WSAStartup failed... aborting - Error %d\n",WSAGetLastError());
		if(!g_bTestMode)
			NotifySCM(SERVICE_STOPPED,0,0);
		return;
	}

	dwTmp=sizeof(szTmpA);
	szNode = NULL;
	if(!RegQueryValueExA(hk,"BindAddress",NULL,&dwType,(BYTE*)szTmpA,&dwTmp))
	{
		if(stricmp(szTmpA,"*"))
			szNode = szTmpA;
	}

	addrinfo hint = {0};
	hint.ai_family=PF_UNSPEC;
	hint.ai_socktype=SOCK_STREAM;
	hint.ai_protocol=IPPROTO_TCP;
	hint.ai_flags=AI_PASSIVE;
	pAddrInfo=NULL;
	if(g_bTestMode)
	{
		printf("Initialising socket...");
	}
	err=getaddrinfo(szNode,szAuthServer,&hint,&pAddrInfo);
	if(g_bTestMode)
	{
		if(err)
			printf("failed (%s)\n",gai_strerror(err));
		else
		{
			if(!pAddrInfo)
			{
				printf("This server doesn't know how to bind tcp sockets!!!  Your sockets layer is broken!!!\n");
			}
			else
				printf("ok\n");
		}
	}
	if(err)
		ReportError(FALSE,"Failed to get ipv4 socket details: %s",gai_strerror(err));

	RegCloseKey(hk);

	if(!g_bTestMode)
		NotifySCM(SERVICE_START_PENDING, 0, seq++);

	int impersonate=1;
	if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\CVS\\Pserver"),0,KEY_QUERY_VALUE,&hk))
	{
		DWORD dwType,dwImpersonate;
		DWORD dwTmp=sizeof(dwTmp);
		if(!RegQueryValueEx(hk,_T("Impersonation"),NULL,&dwType,(BYTE*)&dwImpersonate,&dwTmp))
			impersonate = dwImpersonate;
        RegCloseKey(hk);
        hk = 0;
	
	}
	if(impersonate)
		printf("Impersonation is enabled\n");
	else
		printf("*WARNING* Impersonation is disabled - all file access will be done as System user\n");

	if(g_bTestMode)
		printf("Starting auth server on port %d/tcp...\n",authserver_port);

	addrinfo* ai;
	for(ai=pAddrInfo;ai;ai=ai->ai_next)
	{
		SOCKET s = WSASocket(ai->ai_family,ai->ai_socktype,ai->ai_protocol,NULL,0,0);

		if(s!=-1 && !bind(s,ai->ai_addr,ai->ai_addrlen))
		{
			if(listen(s,50)==SOCKET_ERROR)
			{
				ReportError(TRUE,"Listen on socket failed: %s\n",gai_strerror(WSAGetLastError()));
				if(!g_bTestMode)
					NotifySCM(SERVICE_STOPPED,0,0);
				freeaddrinfo(pAddrInfo);
				return;
			} 
			g_Sockets.push_back(s);
		}
		else
		{
			if(g_bTestMode)
				printf("Socket Failed (Handle=%08x Family=%d,Socktype=%d,Protocol=%d): %s (not fatal)\n",s,ai->ai_family,ai->ai_socktype,ai->ai_protocol, gai_strerror(WSAGetLastError()));
			closesocket(s);
		}
	}
	freeaddrinfo(pAddrInfo);

	if(!g_Sockets.size())
	{
		ReportError(TRUE,"All socket binds failed.");
		if(!g_bTestMode)
			NotifySCM(SERVICE_STOPPED,0,0);
		return;
	}

	DWORD (WINAPI *pDsServerRegisterSpn)(DS_SPN_WRITE_OP Operation, LPCTSTR ServiceClass, LPCTSTR UserObjectDN);

    UINT oldMode=SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
	pDsServerRegisterSpn = (DWORD (WINAPI*)(DS_SPN_WRITE_OP,LPCTSTR,LPCTSTR))GetProcAddress(LoadLibrary("ntdsapi.dll"),"DsServerRegisterSpnA");
	SetErrorMode(oldMode);
	if(pDsServerRegisterSpn)
	{
		if(g_bTestMode)
			printf("Registering service SPN... ");
		pDsServerRegisterSpn(DS_SPN_DELETE_SPN_OP,"cvs",NULL);
		if(!g_bTestMode)
			NotifySCM(SERVICE_START_PENDING, 0, seq++);
		pDsServerRegisterSpn(DS_SPN_DELETE_SPN_OP,"cvs",NULL);
		if(!g_bTestMode)
			NotifySCM(SERVICE_START_PENDING, 0, seq++);
		if((dwTmp=pDsServerRegisterSpn(DS_SPN_ADD_SPN_OP,"cvs",NULL))!=0)
		{
			if(g_bTestMode)
				printf("failed (Error %d)\n",dwTmp);
			//ReportError(TRUE,"Registering cvs service SPN failed (error %d)", dwTmp);
		}
		else
		{
			if(g_bTestMode)
				printf("ok\n");
		}
	}

	// Process running, wait for closedown
	ReportError(FALSE,SERVICE_NAMEA" initialised successfully");
	if(!g_bTestMode)
		NotifySCM(SERVICE_RUNNING, 0, 0);

	g_bStop=FALSE;

	do
	{
		fd_set rfd;
		sockaddr_storage sin;
		size_t n;

		FD_ZERO(&rfd);
		for(n=0; n<g_Sockets.size(); n++)
			FD_SET(g_Sockets[n],&rfd);
		TIMEVAL tv = { 5, 0 }; // 5 seconds max wait
		int sel=select(1,&rfd,NULL,NULL,&tv);
		if(g_bStop || sel==SOCKET_ERROR) break; // Error on socket, or stopped
		for(n=0; n<g_Sockets.size(); n++)
		{
			if(FD_ISSET(g_Sockets[n],&rfd))
			{
				HANDLE hConn=(HANDLE)accept(g_Sockets[n],(struct sockaddr*)&sin,NULL);
				CloseHandle(CreateThread(NULL,0,DoCvsThread,(void*)hConn,0,NULL));
			}
		}
	} while(!g_bStop);

	if(pDsServerRegisterSpn)
	{
		if(g_bTestMode)
			printf("Unregistering service SPN...\n");
		pDsServerRegisterSpn(DS_SPN_DELETE_SPN_OP,"cvs",NULL);
	}
	NotifySCM(SERVICE_STOPPED, 0, 0);
	ReportError(FALSE,SERVICE_NAMEA" stopped successfully");
}
示例#12
0
VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv)
{
    DWORD Status = E_FAIL;

    addLog("Print Service: ServiceMain: Entry");

    g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler);

    if (g_StatusHandle == NULL)
    {
        addLog("Print Service: ServiceMain: RegisterServiceCtrlHandler returned error");
        return;
    }
    ZeroMemory (&g_ServiceStatus, sizeof (g_ServiceStatus));
    g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwServiceSpecificExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;

    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        addLog("Print Service: ServiceMain: SetServiceStatus returned error");
    }
   addLog("Print Service: ServiceMain: Performing Service Start Operations");

    g_ServiceStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
    if (g_ServiceStopEvent == NULL)
    {
        addLog("Print Service: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error");

        g_ServiceStatus.dwControlsAccepted = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwWin32ExitCode = GetLastError();
        g_ServiceStatus.dwCheckPoint = 1;

        if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
        {
           addLog("Print Service: ServiceMain: SetServiceStatus returned error");
        }
        return;
    }
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;

    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        addLog("Print Service: ServiceMain: SetServiceStatus returned error");
    }
    HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

    addLog("Print Service: ServiceMain: Waiting for Worker Thread to complete");
    WaitForSingleObject (hThread, INFINITE);
    addLog("Print Service: ServiceMain: Worker Thread Stop Event signaled");
    addLog("Print Service: ServiceMain: Performing Cleanup Operations");

    CloseHandle (g_ServiceStopEvent);

    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 3;

    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) {
        addLog("Print Service: ServiceMain: SetServiceStatus returned error");
    }
    addLog("Print Service: ServiceMain: Exit");
    return;
}
示例#13
0
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
	DWORD Status = E_FAIL;

	OutputDebugString(_T("GDaemon: ServiceMain: Entry"));

	g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);

	if (g_StatusHandle == NULL)
	{
		OutputDebugString(_T("GDaemon: ServiceMain: RegisterServiceCtrlHandler returned error"));
		return;
	}

	// Tell the service controller we are starting
	ZeroMemory(&g_ServiceStatus, sizeof (g_ServiceStatus));
	g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	g_ServiceStatus.dwControlsAccepted = 0;
	g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
	g_ServiceStatus.dwWin32ExitCode = 0;
	g_ServiceStatus.dwServiceSpecificExitCode = 0;
	g_ServiceStatus.dwCheckPoint = 0;

	if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
	{
		OutputDebugString(_T("GDaemon: ServiceMain: SetServiceStatus returned error"));
	}

	/*
	* Perform tasks neccesary to start the service here
	*/
	OutputDebugString(_T("GDaemon: ServiceMain: Performing Service Start Operations"));

	// Create stop event to wait on later.
	g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (g_ServiceStopEvent == NULL)
	{
		OutputDebugString(_T("GDaemon: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error"));

		g_ServiceStatus.dwControlsAccepted = 0;
		g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
		g_ServiceStatus.dwWin32ExitCode = GetLastError();
		g_ServiceStatus.dwCheckPoint = 1;

		if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
		{
			OutputDebugString(_T("GDaemon: ServiceMain: SetServiceStatus returned error"));
		}
		
		return;
	}

	// Tell the service controller we are started
	g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
	g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
	g_ServiceStatus.dwWin32ExitCode = 0;
	g_ServiceStatus.dwCheckPoint = 0;

	if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
	{
		OutputDebugString(_T("GDaemon: ServiceMain: SetServiceStatus returned error"));
	}

	// Start the thread that will perform the main task of the service
	HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

	OutputDebugString(_T("GDaemon: ServiceMain: Waiting for Worker Thread to complete"));

	// Wait until our worker thread exits effectively signaling that the service needs to stop
	WaitForSingleObject(hThread, INFINITE);

	OutputDebugString(_T("GDaemon: ServiceMain: Worker Thread Stop Event signaled"));


	/*
	* Perform any cleanup tasks
	*/
	OutputDebugString(_T("GDaemon: ServiceMain: Performing Cleanup Operations"));

	CloseHandle(g_ServiceStopEvent);

	g_ServiceStatus.dwControlsAccepted = 0;
	g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
	g_ServiceStatus.dwWin32ExitCode = 0;
	g_ServiceStatus.dwCheckPoint = 3;

	if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
	{
		OutputDebugString(_T("GDaemon: SetServiceStatus returned error"));
	}

	return;
}
示例#14
0
文件: service.c 项目: AzerTyQsdF/osx
void __stdcall service_main_fn(DWORD argc, LPTSTR *argv)
{
    HANDLE hCurrentProcess;
    HANDLE hPipeRead = NULL;
    HANDLE hPipeReadDup;
    HANDLE hNullFile;
    DWORD  threadid;
    SECURITY_ATTRIBUTES sa = {0};
    char **newargv;

    if(!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], 
                                                             service_ctrl)))
    {
        ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
        "Failure registering service handler");
        return;
    }

    ReportStatusToSCMgr(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        3000);                 // wait hint

    /* Create a pipe to send stderr messages to the system error log */
    hCurrentProcess = GetCurrentProcess();
    if (CreatePipe(&hPipeRead, &eventlog_pipewrite, &sa, 0)) 
    {
        if (DuplicateHandle(hCurrentProcess, hPipeRead, hCurrentProcess,
                            &hPipeReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
        {
            CloseHandle(hPipeRead);
            hPipeRead = hPipeReadDup;
            eventlog_thread = CreateThread(NULL, 0, service_stderr_thread, 
                                           (LPVOID) hPipeRead, 0, &threadid);
            if (eventlog_thread)
            {
                int fh;
                FILE *fl;
            	fflush(stderr);
		SetStdHandle(STD_ERROR_HANDLE, eventlog_pipewrite);
				
                fh = _open_osfhandle((long) STD_ERROR_HANDLE, 
                                     _O_WRONLY | _O_BINARY);
                dup2(fh, STDERR_FILENO);
                fl = _fdopen(STDERR_FILENO, "wcb");
                memcpy(stderr, fl, sizeof(FILE));
            }
            else
            {
                CloseHandle(hPipeRead);
                CloseHandle(eventlog_pipewrite);
                eventlog_pipewrite = NULL;
            }            
        }
        else
        {
            CloseHandle(hPipeRead);
            CloseHandle(eventlog_pipewrite);
            eventlog_pipewrite = NULL;
        }            
    }

    /* Open a null handle to nak our stdin */
    hNullFile = CreateFile("nul", GENERIC_READ | GENERIC_WRITE, 
                           FILE_SHARE_READ | FILE_SHARE_WRITE, 
                           &sa, OPEN_EXISTING, 0, NULL);
    if (hNullFile == INVALID_HANDLE_VALUE) {
        ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, NULL,
                     "Parent: Unable to create null stdin pipe for this service process.\n");
    }
    else {
        int fh;
        FILE *fl;
        fflush(stdin);
	SetStdHandle(STD_INPUT_HANDLE, hNullFile);
        fh = _open_osfhandle((long) STD_INPUT_HANDLE, 
                             _O_RDONLY | _O_BINARY);
        dup2(fh, STDIN_FILENO);
        fl = _fdopen(STDIN_FILENO, "rcb");
        memcpy(stdin, fl, sizeof(FILE));
    }

    /* Open a null handle to soak our stdout */
    hNullFile = CreateFile("nul", GENERIC_READ | GENERIC_WRITE, 
                           FILE_SHARE_READ | FILE_SHARE_WRITE, 
                           &sa, OPEN_EXISTING, 0, NULL);
    if (hNullFile == INVALID_HANDLE_VALUE) {
        ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, NULL,
                     "Parent: Unable to create null stdout pipe for this service process.\n");
    }
    else {
        int fh;
        FILE *fl;
        fflush(stdout);
	SetStdHandle(STD_OUTPUT_HANDLE, hNullFile);
        fh = _open_osfhandle((long) STD_OUTPUT_HANDLE, 
                             _O_WRONLY | _O_BINARY);
        dup2(fh, STDOUT_FILENO);
        fl = _fdopen(STDOUT_FILENO, "wcb");
        memcpy(stdout, fl, sizeof(FILE));
    }

    /* Grab it or lose it */
    globdat.name = argv[0];

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
             "Hooked up the Service Error Event Logger.");

    /* Fold the "Start Parameters" in with the true executable argv[0],
     * and insert a -n tag to pass the service name from the SCM's argv[0]
     */
    newargv = (char**) malloc((argc + 3) * sizeof(char*));
    newargv[0] = ap_server_argv0;  /* The true executable name */
    newargv[1] = "-n";             /* True service name follows (argv[0]) */
    memcpy (newargv + 2, argv, argc * sizeof(char*));
    newargv[argc + 2] = NULL;      /* SCM doesn't null terminate the array */
    argv = newargv;
    argc += 2;

    /* Use the name of the service as the error log marker */
    ap_server_argv0 = globdat.name;

    globdat.exit_status = globdat.main_fn( argc, argv );
}
示例#15
0
VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv)
{
    DWORD Status = E_FAIL;
 
    g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler);
 
    if (g_StatusHandle == nullptr) 
    {
        return;
    }
 
    ZeroMemory (&g_ServiceStatus, sizeof (g_ServiceStatus));
    g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwServiceSpecificExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;
 
    if (SetServiceStatus (g_StatusHandle , &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T("NewYearGarland: ServiceMain: SetServiceStatus returned error"));
    }
 
    g_ServiceStopEvent = CreateEvent (nullptr, TRUE, FALSE, nullptr);
    if (g_ServiceStopEvent == nullptr) 
    {   
        g_ServiceStatus.dwControlsAccepted = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwWin32ExitCode = GetLastError();
        g_ServiceStatus.dwCheckPoint = 1;
 
		if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
		{
			OutputDebugString(_T("NewYearGarland: ServiceMain: SetServiceStatus returned error"));
		}
		return;
    }    
    
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;
 
    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T("NewYearGarland: ServiceMain: SetServiceStatus returned error"));
    }

    HANDLE hThread = CreateThread (nullptr, 0, ServiceWorkerThread, nullptr, 0, nullptr);
   
    WaitForSingleObject (hThread, INFINITE);

    CloseHandle (g_ServiceStopEvent);
 
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 3;
 
    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T("NewYearGarland: ServiceMain: SetServiceStatus returned error"));
    }
} 
示例#16
0
void
ArchDaemonWindows::serviceMain(DWORD argc, LPTSTR* argvIn)
{
	typedef std::vector<LPCTSTR> ArgList;
	typedef std::vector<std::string> Arguments;
	const char** argv = const_cast<const char**>(argvIn);

	// create synchronization objects
	m_serviceMutex        = ARCH->newMutex();
	m_serviceCondVar      = ARCH->newCondVar();
	
	// register our service handler function
	m_statusHandle = RegisterServiceCtrlHandler(argv[0],
								&ArchDaemonWindows::serviceHandlerEntry);
	if (m_statusHandle == 0) {
		// cannot start as service
		m_daemonResult = -1;
		ARCH->closeCondVar(m_serviceCondVar);
		ARCH->closeMutex(m_serviceMutex);
		return;
	}

	// tell service control manager that we're starting
	m_serviceState = SERVICE_START_PENDING;
	setStatus(m_serviceState, 0, 10000);

	std::string commandLine;

	// if no arguments supplied then try getting them from the registry.
	// the first argument doesn't count because it's the service name.
	Arguments args;
	ArgList myArgv;
	if (argc <= 1) {
		// read command line
		HKEY key = openNTServicesKey();
		key      = ArchMiscWindows::openKey(key, argvIn[0]);
		key      = ArchMiscWindows::openKey(key, _T("Parameters"));
		if (key != NULL) {
			commandLine = ArchMiscWindows::readValueString(key,
												_T("CommandLine"));
		}

		// if the command line isn't empty then parse and use it
		if (!commandLine.empty()) {
			// parse, honoring double quoted substrings
			std::string::size_type i = commandLine.find_first_not_of(" \t");
			while (i != std::string::npos && i != commandLine.size()) {
				// find end of string
				std::string::size_type e;
				if (commandLine[i] == '\"') {
					// quoted.  find closing quote.
					++i;
					e = commandLine.find("\"", i);

					// whitespace must follow closing quote
					if (e == std::string::npos ||
						(e + 1 != commandLine.size() &&
						commandLine[e + 1] != ' ' &&
						commandLine[e + 1] != '\t')) {
						args.clear();
						break;
					}

					// extract
					args.push_back(commandLine.substr(i, e - i));
					i = e + 1;
				}
				else {
					// unquoted.  find next whitespace.
					e = commandLine.find_first_of(" \t", i);
					if (e == std::string::npos) {
						e = commandLine.size();
					}

					// extract
					args.push_back(commandLine.substr(i, e - i));
					i = e + 1;
				}

				// next argument
				i = commandLine.find_first_not_of(" \t", i);
			}

			// service name goes first
			myArgv.push_back(argv[0]);

			// get pointers
			for (size_t j = 0; j < args.size(); ++j) {
				myArgv.push_back(args[j].c_str());
			}

			// adjust argc/argv
			argc = (DWORD)myArgv.size();
			argv = &myArgv[0];
		}
	}

	m_commandLine = commandLine;

	try {
		// invoke daemon function
		m_daemonResult = m_daemonFunc(static_cast<int>(argc), argv);
	}
	catch (XArchDaemonRunFailed& e) {
		setStatusError(e.m_result);
		m_daemonResult = -1;
	}
	catch (...) {
		setStatusError(1);
		m_daemonResult = -1;
	}

	// clean up
	ARCH->closeCondVar(m_serviceCondVar);
	ARCH->closeMutex(m_serviceMutex);

	// we're going to exit now, so set status to stopped
	m_serviceState = SERVICE_STOPPED;
	setStatus(m_serviceState, 0, 10000);
}
示例#17
0
void WINAPI TimeServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) 
{
#ifdef _WIN64
   unsigned __int64 dwCompKey  = CK_SERVICECONTROL;
#else
   DWORD dwCompKey  = CK_SERVICECONTROL;
#endif
   DWORD fdwControl = SERVICE_CONTROL_RUN;
   DWORD dwBytesTransferred;
   OVERLAPPED *po;
   SERVICE_STATUS ss;
   SERVICE_STATUS_HANDLE hSS;
   BOOL bPasswordCompileEmbedded = 0;

// We must get the private password for connecting to this machine.
// The password can be compiled into the server any of the following ways......


//  1 way - the easiest way, just uncomment and put any value between the quotes
//  then remove the code between --Load External Password Begin & End-- below
//  ***** example of very simple integrated password ********
//  GString strPassword("Password");
//	GString strPort("80");
//	GString strRoot;
//	bPasswordCompileEmbedded = 1;


//  Another way - a most secure way to embed the password.
//  ***** example of integrated password ********
//  GString strPassword;
//	MakePassword(strPassword);    // Go read the MakePassword() routine above.
//	GString strPort("80");
//	GString strRoot;
//	bPasswordCompileEmbedded = 1;


//              OR

// The password can be retrieved from an external disk location.
// Passwords can be obtained from disk in two different ways.
// Either in a registry key matching the (probably renamed) 
// executable file that is this server, OR by loading a 
// predefined file name at a predefined location. 
// This file must be present while starting the server, but can be
// removed once this process has fully started.


//  --Load External Password Begin--
GString strPassword;
GString strPort;
GString strRoot;

if (!bPasswordCompileEmbedded)
{
	GString strThisEXEName(GetThisEXEName());
	GString strStartupKey;

	// use our runtime image name as the registry key
	char buf[512];
	long lSize = sizeof(buf);
	if (RegQueryValue(HKEY_CLASSES_ROOT,(const char *)strThisEXEName,buf,&lSize) == ERROR_SUCCESS)
	{
		// uudecode the startup key
		BUFFER b;
		BufferInit(&b);
		unsigned int nDecoded;
		uudecode(buf, &b, &nDecoded, false);
		strStartupKey.write((const char *)b.pBuf,nDecoded);
		BufferTerminate(&b);
	}

	GString strStartupData;
	if (strStartupKey.Length())
	{
		// look for a file in the root of the file system (c:\)
		// with the same name as this .exe
		GString strFile("c:\\");
		strFile += strThisEXEName;


		// load the crypted disk file into clear text memory
		char *pDest;
		int nDestLen;
		GString strErrorOut;
		if (FileDecryptToMemory(strStartupKey, strFile, &pDest, &nDestLen, strErrorOut))
		{
			// parse into the profile data structures
			pDest[7 + nDestLen] = 0; // null terminate it
			strStartupData.write(&pDest[7], nDestLen + 1); // and cap the GString 
		}
		else
		{
			// if the file was not in the root of the file system
			// see if there is an environment setting directing
			// this server to look for the file in another location
			// The variable name is dynamic, matching this .exe name
			// and the environment variable value must be a fully
			// qualified path and file name to the startup file.
			if (getenv(strThisEXEName))
			{
				if (FileDecryptToMemory(strStartupKey, getenv(strThisEXEName), &pDest, &nDestLen, strErrorOut))
				{
					// parse into the profile data structures
					strStartupData.write(&pDest[7], nDestLen-7);
				}
			}
		}

		// parse stored settings in startup file to startup variables
		if (strStartupData.Length())
		{
			GStringList lstOptions("&&",strStartupData);
			GStringIterator it(&lstOptions);

			if (it()) strPassword = it++;
			if (it()) strRoot = it++; // currently not used
			if (it()) strPort = it++;
		}
	}
}

//  --Load External Password End--

	GString strFile;
	GString strConfigFileDefault;
	GString strErrorOut;
	int bSetStartupFile = 0;

#ifdef _WIN32
	SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); // = 1 point above normal
#endif


   // Create the completion port and save its handle in a global
   // variable so that the Handler function can access it.
   g_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, CK_PIPE, 0);

   // Give SCM the address of this service's Handler
   // NOTE: hSS does not have to be closed.
   hSS = RegisterServiceCtrlHandler((const char *)strServerName, TimeServiceHandler);

   // Do what the service should do.
   // Initialize the members that never change
   ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 
   ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | 
      SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;

   do {
      switch (dwCompKey) {
      case CK_SERVICECONTROL:
         // We got a new control code
         ss.dwWin32ExitCode = NO_ERROR; 
         ss.dwServiceSpecificExitCode = 0; 
         ss.dwCheckPoint = 0; 
         ss.dwWaitHint = 0;

         if (fdwControl == SERVICE_CONTROL_INTERROGATE) {
            SetServiceStatus(hSS, &ss);
            break;
         }

         // Determine which PENDING state to return
         if (dwSrvCtrlToPend[fdwControl] != 0) {
            ss.dwCurrentState = dwSrvCtrlToPend[fdwControl]; 
            ss.dwCheckPoint = 0;
            ss.dwWaitHint = 500;   // half a second
            SetServiceStatus(hSS, &ss);
         }

         switch (fdwControl) {
            case SERVICE_CONTROL_RUN:
            case SERVICE_CONTROL_CONTINUE:
				try
				{
					if (strRoot.Length() && strPort.Length())
					{
						GString strCfgData;
						strCfgData.Format(pzBoundStartupConfig,(const char *)strRoot,(const char *)strPort);
						SetProfile(new GProfile((const char *)strCfgData, (int)strCfgData.Length(), 0));

						if (!server_start())
						{
							ss.dwCurrentState = SERVICE_STOPPED; 
							ss.dwCheckPoint = ss.dwWaitHint = 0;
							SetServiceStatus(hSS, &ss);
							break;
						}
					}
					else
					{
						// No password compiled in - and no valid startup file found
						for(int i=0; i<3;i++)
						{
							// three beeps
							MessageBeep(0);
							Sleep(1000);
						}
						ss.dwCurrentState = SERVICE_STOPPED; 
						ss.dwCheckPoint = ss.dwWaitHint = 0;
						SetServiceStatus(hSS, &ss);
						break;
					}
				}
				catch ( GException &)
				{
					ss.dwCurrentState = SERVICE_STOPPED; 
					ss.dwCheckPoint = ss.dwWaitHint = 0;
					SetServiceStatus(hSS, &ss);
					break;
				}



				if (dwSrvPendToState[ss.dwCurrentState] != 0) 
				{
					ss.dwCurrentState = dwSrvPendToState[ss.dwCurrentState]; 
					ss.dwCheckPoint = ss.dwWaitHint = 0;
					SetServiceStatus(hSS, &ss);
				}
				break;

            case SERVICE_CONTROL_PAUSE:
            case SERVICE_CONTROL_STOP:
            case SERVICE_CONTROL_SHUTDOWN:
                server_stop();
				if (dwSrvPendToState[ss.dwCurrentState] != 0) 
				{
					ss.dwCurrentState = dwSrvPendToState[ss.dwCurrentState]; 
					ss.dwCheckPoint = ss.dwWaitHint = 0;
					SetServiceStatus(hSS, &ss);
				}
				break;
         }

         // Determine which complete state to return
         break;

      }

      if (ss.dwCurrentState != SERVICE_STOPPED) {
         // Sleep until a control code comes in or a client connects
         GetQueuedCompletionStatus(g_hIOCP, &dwBytesTransferred,
            &dwCompKey, &po, INFINITE);
         fdwControl = dwBytesTransferred;
      }
   } while (ss.dwCurrentState != SERVICE_STOPPED);

   // Cleanup and stop this service
   CloseHandle(g_hIOCP);   
}
      // scm service thread
      void service_main(DWORD dw_argc, LPTSTR* lpsz_argv)
      {
         string_type void_string;

         // like this service is SERVICE_WIN32_OWN_PROCESS,
         // then the RegisterServiceCtrlHandler
         // function does not verify if the name is valid, because there is only
         // one registered service in the process. can be  "" (void_string)
         service_status_handle_ =
            RegisterServiceCtrlHandler( (char_type*)void_string.c_str(),
            (LPHANDLER_FUNCTION) service_handler_entry);

         if (!service_status_handle_)
         {
            return;
         }

         // notify SCM of progress
         if (!send_status_to_scm(SERVICE_START_PENDING, 1, 1000))
         {
            send_status_to_scm(SERVICE_STOPPED, 0, 0, GetLastError());
            return;
         }

         // create the termination event
         terminate_event_ = CreateEvent (0, TRUE, FALSE, 0);

         if (!terminate_event_)
         {
            send_status_to_scm(SERVICE_STOPPED, 0, 0, GetLastError());
            return;
         }

         // notify SCM of progress
         if (!send_status_to_scm(SERVICE_START_PENDING, 2, 5000))
         {
            send_status_to_scm(SERVICE_STOPPED, 0, 0, GetLastError());
            return;
         }

         // Launch work thread (main)
         launch_thread_ = new csbl::thread(
            boost::bind(&server_application_impl_::work_thread, this, dw_argc, lpsz_argv));

         HANDLE hevent[2];

         hevent[0] = launch_thread_->native_handle();
         if(hevent[0] == NULL)
         {
            send_status_to_scm(SERVICE_STOPPED, 0, 0, -1);
            return;
         }

         // The service is now running.
         // Notify SCM of progress
         if (!send_status_to_scm(SERVICE_RUNNING, 0, 0))
         {
            terminate(GetLastError());
            return;
         }

         hevent[1] = terminate_event_;

         // Wait for stop signal, and then terminate
         WaitForMultipleObjects(2,hevent,FALSE,INFINITE);

         if (!send_status_to_scm(SERVICE_STOP_PENDING, 1, 5000))
         {
            terminate(GetLastError());
            return;
         }
         // terminate service, no error!
         terminate(result_code_);
      }
示例#19
0
/*
* Service Main function - Called by the SCM after the service has started
*/
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
	gServiceHandle = RegisterServiceCtrlHandler(g_serviceName, ServiceCtrlHandler);
	if (gServiceHandle == 0)
	{
		logStartError("RegisterServiceCtrlHandler failed.");
	}
	else
	{
		// signal service is starting
		setServiceStatus(SERVICE_START_PENDING, TRUE, NO_ERROR, 3000);

		// create event for when service is signaled to stop
		g_serviceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (g_serviceStopEvent)
		{
			TCHAR szPath[MAX_PATH];
			char *last_slash;

			GetModuleFileName(NULL, szPath, MAX_PATH);
			last_slash = s_strrchr(szPath, '\\', MAX_PATH);
			if (NULL != last_slash)
				*last_slash = '\0';

			if (SetCurrentDirectory(szPath))
			{
				std::vector<monitor::NvmMonitorBase *> monitors;
				monitor::NvmMonitorBase::getMonitors(monitors);

				size_t handleCount = monitors.size() + 1; // +1 to also add g_serviceStopEvent
				HANDLE handles[handleCount];
				for (size_t i = 0; i < monitors.size(); i++)
				{
					handles[i] =
							CreateThread(NULL, 0, WorkerThread, (LPVOID) (monitors[i]), 0, NULL);
				}

				// In the case there are no monitor items, adding the stop event will keep the
				// service running until a Service Stop Event occurs.
				handles[handleCount - 1] = g_serviceStopEvent;

				// now running
				setServiceStatus(SERVICE_RUNNING, false, NO_ERROR, 0);

				// wait for all threads to end and Service Stop Event
				WaitForMultipleObjects(handleCount, handles, true, INFINITE);

				// clean up
				for (size_t i = 0; i < handleCount; i++)
				{
					CloseHandle(handles[i]);
				}
				monitor::NvmMonitorBase::deleteMonitors(monitors);

				setServiceStatus(SERVICE_STOPPED, FALSE, NO_ERROR, 0);
			}
			else
			{
				logStartError("Failed to set working directory.");
				setServiceStatus(SERVICE_STOPPED, FALSE, NO_ERROR, 0);
			}

		}
		else
		{
			logStartError("CreateEvent Failed");
			setServiceStatus(SERVICE_STOPPED, FALSE, NO_ERROR, 0);
		}


	}
}
示例#20
0
void WINAPI ServiceMain(DWORD argc, LPTSTR argv[])
{
	bool bConnected; 
    CHAR chRequest[MAX_PATH + 1]; 
    DWORD cbBytesRead, cbTotalBytes; 
    BOOL bSuccess; 
	char* szData = new char[BUFFER_SIZE];
	char* szArguments = NULL;
    HANDLE hPipe; 

	SERVICE_STATUS ss = { SERVICE_WIN32_OWN_PROCESS, SERVICE_START_PENDING, SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, NO_ERROR, 0, 1, 5000 };
	
	hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	
	g_hServiceStatus = RegisterServiceCtrlHandler(SERVICE_NAME, ControlHandler);
	if (!g_hServiceStatus)
	{
		delete szData;
 		ss.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(g_hServiceStatus, &ss);
		return;
	}

	if (!SetServiceStatus(g_hServiceStatus, &ss))
	{
		delete szData;
 		ss.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(g_hServiceStatus, &ss);
		return;
	}

	ss.dwCheckPoint++;
	if (!SetServiceStatus(g_hServiceStatus, &ss))
	{
		delete szData;
 		ss.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(g_hServiceStatus, &ss);
		return;
	}

    hPipe = CreateNamedPipe(g_szPipeName, 
                            PIPE_ACCESS_DUPLEX, // read/write access 
                            PIPE_TYPE_MESSAGE | // message type pipe 
                            PIPE_READMODE_MESSAGE | // message-read mode 
                            PIPE_WAIT, // non-blocking mode 
                            PIPE_UNLIMITED_INSTANCES, // max. instances 
                            BUFSIZE, // output buffer size 
                            MAX_PATH, // input buffer size 
                            1000, // client time-out 
                            NULL); // no security attribute 

    if (hPipe == INVALID_HANDLE_VALUE) 
	{
		delete szData;
 		ss.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(g_hServiceStatus, &ss);
		return;
	}
	
	ss.dwCheckPoint = 0;
	ss.dwCurrentState = SERVICE_RUNNING;
	ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;
	if (!SetServiceStatus(g_hServiceStatus, &ss))
	{
		delete szData;
		ss.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(g_hServiceStatus, &ss);
		return;
	}

    bConnected = ConnectNamedPipe(hPipe, NULL) ? true : (GetLastError() == ERROR_PIPE_CONNECTED || GetLastError() == ERROR_PIPE_LISTENING); 

    while(bConnected) 
    { 
		if (WaitForSingleObject(hStopEvent, 1000) == WAIT_OBJECT_0)
		{
			ss.dwCheckPoint = 1;
			ss.dwCurrentState = SERVICE_STOP_PENDING;
			ss.dwWaitHint = 2000;
			SetServiceStatus(g_hServiceStatus, &ss);
			break;		// Stop the service now
		}

        if (bConnected) 
        { 
			memset(chRequest, 0, MAX_PATH);
			//bSuccess = PeekNamedPipe(hPipe, chRequest, MAX_PATH, &cbBytesRead, &cbTotalBytes, &cbBytesLeft);
			bSuccess = ReadFile(hPipe, chRequest, MAX_PATH, &cbBytesRead, NULL); 
			if (bSuccess && cbBytesRead > 0)
			{
				chRequest[cbBytesRead] = '\0';
				//FlushFileBuffers(hPipe); 

				// Try to execute the command
				::ZeroMemory(szData, BUFFER_SIZE);

				// See if there is a "||" sequence in the command - if so, it separates the arguments and the command
				if (strstr(chRequest, "||") != NULL)
				{
					szArguments = strstr(chRequest, "||");
					*szArguments = '\0';	// Make this the end of the string
					szArguments += 2;
				}
				if (ExecuteCommand(chRequest, szArguments, 120000, &szData, BUFFER_SIZE)) // 2 minute timeout
				{
					WriteFile(hPipe, szData, strlen(szData), &cbTotalBytes, NULL);
				}
				else
				{
					char szError[256];
					::ZeroMemory(szError, 256);
					_snprintf_s(szError, 256, sizeof(GetLastError())+37, "Exec failed, GetLastError returned %d\n", GetLastError());
					WriteFile(hPipe, szError, strlen(szError), &cbTotalBytes, NULL);
				}

				FlushFileBuffers(hPipe); 
				DisconnectNamedPipe(hPipe);
				bConnected = ConnectNamedPipe(hPipe, NULL) ? true : (GetLastError() == ERROR_PIPE_CONNECTED || GetLastError() == ERROR_PIPE_LISTENING); 
			}
        }
    } 

    CloseHandle(hPipe); 
	CloseHandle(hStopEvent);

	ss.dwCurrentState = SERVICE_STOPPED;
	SetServiceStatus(g_hServiceStatus, &ss);
	delete szData;
}
示例#21
0
static void 
#if defined(_WIN32)
	WINAPI
#endif
service_loop(int argc, char** argv)
{
	int		argn;
	char*	arg;
	char	str[128];
	char	compiler[128];

	for(argn=1; argn<(int)argc; argn++) {
		arg=argv[argn];
		if(*arg!='-') {	/* .ini file specified */
			if(!fexist(arg)) {
				lprintf(LOG_ERR,"Initialization file does not exist: %s", arg);
				exit(usage(argv[0]));
			}
			parse_ini_file(arg);
			continue;
		}
		while(*arg=='-') 
			arg++;
		if(stricmp(arg,"null")==0)
			mdm_null=TRUE;
		else if(stricmp(arg,"com")==0 && argc > argn+1)
			SAFECOPY(com_dev, argv[++argn]);
		else if(stricmp(arg,"baud")==0 && argc > argn+1)
			com_baudrate = (ulong)strtol(argv[++argn],NULL,0);
		else if(stricmp(arg,"host")==0 && argc > argn+1)
			SAFECOPY(host, argv[++argn]);
		else if(stricmp(arg,"port")==0 && argc > argn+1)
			port = (ushort)strtol(argv[++argn], NULL, 0);
		else if(stricmp(arg,"live")==0) {
			if(argc > argn+1 &&
				(com_handle = (COM_HANDLE)strtol(argv[argn+1], NULL, 0)) != 0) {
				argn++;
				com_handle_passed=TRUE;
			}
			com_alreadyconnected=TRUE;
			terminate_after_one_call=TRUE;
			mdm_null=TRUE;
		}
		else if(stricmp(arg,"nohangup")==0) {
			com_hangup=FALSE;
		}
		else if(stricmp(arg,"debug")==0) {
			log_level=LOG_DEBUG;
		}
		else if(stricmp(arg,"help")==0 || *arg=='?')
			exit(usage(argv[0]));
		else {
			fprintf(stderr,"Invalid option: %s\n", arg);
			exit(usage(argv[0]));
		}
	}

#if defined(_WIN32)
	/* Convert "1" to "COM1" for Windows */
	{
		int i;

		if((i=atoi(com_dev)) != 0)
			SAFEPRINTF(com_dev, "COM%d", i);
	}

	if(daemonize) {

		if((svc_status_handle = RegisterServiceCtrlHandler(NAME, ServiceControlHandler))==0) {
			lprintf(LOG_ERR,"!ERROR %d registering service control handler",GetLastError());
			return;
		}

		svc_status.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
		svc_status.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN;
		svc_status.dwWaitHint=NTSVC_TIMEOUT_STARTUP;

		svc_status.dwCurrentState=SERVICE_START_PENDING;
		SetServiceStatus(svc_status_handle, &svc_status);
	}

#endif

	lprintf(LOG_INFO,"%s", comVersion(str,sizeof(str)));
	DESCRIBE_COMPILER(compiler);
	lprintf(LOG_INFO,"Build %s %s %s", __DATE__, __TIME__, compiler);

	/************************************/
	/* Inititalize WinSock and COM Port */
	/************************************/

	if(!winsock_startup())
		exit(1);

	/* Install clean-up callback */
	atexit(cleanup);

	lprintf(LOG_INFO,"TCP Host: %s", host);
	lprintf(LOG_INFO,"TCP Port: %u", port);
	
	if(!com_handle_passed) {
		lprintf(LOG_INFO,"Opening Communications Device (COM Port): %s", com_dev);
		if((com_handle=comOpen(com_dev)) == COM_HANDLE_INVALID) {
			lprintf(LOG_ERR,"ERROR %u opening communications device/port: '%s'", COM_ERROR_VALUE, com_dev);
			exit(1);
		}
	}
	lprintf(LOG_INFO,"COM Port device handle: %u", com_handle);

	if(com_baudrate!=0) {
		if(!comSetBaudRate(com_handle,com_baudrate))
			lprintf(LOG_ERR,"ERROR %u setting DTE rate to %lu bps"
				,COM_ERROR_VALUE, com_baudrate);
	}

	lprintf(LOG_INFO,"COM Port DTE rate: %ld bps", comGetBaudRate(com_handle));

	if(ident)
		_beginthread(ident_server_thread, 0, NULL);

#if defined(_WIN32)
	if(daemonize) {
		svc_status.dwCurrentState=SERVICE_RUNNING;
		svc_status.dwControlsAccepted|=SERVICE_ACCEPT_STOP;
		SetServiceStatus(svc_status_handle, &svc_status);
	}
#endif

	/***************************/
	/* Initialization Complete */
	/***************************/

	/* Main service loop: */
	while(!terminated && wait_for_call(com_handle)) {
		if(!carrier_detect(com_handle))	/* re-initialization timer time-out? */
			continue;
		comWriteByte(com_handle,'\r');
		comWriteString(com_handle, banner);
		comWriteString(com_handle, "\r\n");
		if((sock=connect_socket(host, port)) == INVALID_SOCKET) {
			comWriteString(com_handle,"\7\r\n!ERROR connecting to TCP port\r\n");
		} else {
			handle_call();
			close_socket(&sock);
			total_calls++;
			lprintf(LOG_INFO,"Call completed (%lu total)", total_calls);
		}
		if(com_hangup && !hangup_call(com_handle))
			break;
		if(terminate_after_one_call)
			break;
	}

	exit(0);
}
示例#22
0
/**
 * The main function for the service.
 * Called by the services API when starting unbound on windows in background.
 * Arguments could have been present in the string 'path'.
 * @param argc: nr args
 * @param argv: arg text.
 */
static void 
service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv))
{
	struct config_file* cfg = NULL;
	struct daemon* daemon = NULL;

	service_status_handle = RegisterServiceCtrlHandler(SERVICE_NAME, 
		(LPHANDLER_FUNCTION)hdlr);
	if(!service_status_handle) {
		reportev("Could not RegisterServiceCtrlHandler");
		return;
	}
	
	service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	service_status.dwServiceSpecificExitCode = 0;

	/* see if we have root anchor update enabled */
	call_root_update();

	/* we are now starting up */
	report_status(SERVICE_START_PENDING, NO_ERROR, 3000);
	if(!service_init(0, &daemon, &cfg)) {
		reportev("Could not service_init");
		report_status(SERVICE_STOPPED, NO_ERROR, 0);
		return;
	}

	/* event that gets signalled when we want to quit; it
	 * should get registered in the worker-0 waiting loop. */
	service_stop_event = WSACreateEvent();
	if(service_stop_event == WSA_INVALID_EVENT) {
		log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError()));
		reportev("Could not WSACreateEvent");
		report_status(SERVICE_STOPPED, NO_ERROR, 0);
		return;
	}
	if(!WSAResetEvent(service_stop_event)) {
		log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError()));
	}

	/* SetServiceStatus SERVICE_RUNNING;*/
	report_status(SERVICE_RUNNING, NO_ERROR, 0);
	verbose(VERB_QUERY, "winservice - init complete");

	/* daemon performs work */
	while(!service_stop_shutdown) {
		daemon_fork(daemon);
		if(!service_stop_shutdown) {
			daemon_cleanup(daemon);
			config_delete(cfg); cfg=NULL;
			if(!service_init(1, &daemon, &cfg)) {
				reportev("Could not service_init");
				report_status(SERVICE_STOPPED, NO_ERROR, 0);
				return;
			}
		}
	}

	/* exit */
	verbose(VERB_ALGO, "winservice - cleanup.");
	report_status(SERVICE_STOP_PENDING, NO_ERROR, 0);
	service_deinit(daemon, cfg);
	free(service_cfgfile);
	if(service_stop_event) (void)WSACloseEvent(service_stop_event);
	verbose(VERB_QUERY, "winservice - full stop");
	report_status(SERVICE_STOPPED, NO_ERROR, 0);
}
示例#23
0
static void WINAPI StartService(DWORD /*argc*/, char* argv[]) {
	ssh = RegisterServiceCtrlHandler(argv[0], CtrlHandler);
	
	if(ssh == NULL) {
		AppendLog("RegisterServiceCtrlHandler failed ("+string((uint32_t)GetLastError())+")!");
	    return;
	}
	
	ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	ss.dwCurrentState = SERVICE_START_PENDING;
	ss.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
	ss.dwWin32ExitCode = NO_ERROR;
	ss.dwCheckPoint = 0;
	ss.dwWaitHint = 10 * 1000;
	
	if(SetServiceStatus(ssh, &ss) == false) {
		AppendLog("StartService::SetServiceStatus failed ("+string((uint32_t)GetLastError())+")!");
		return;
	}
	
	ServerInitialize();
	
	if(ServerStart() == false) {
	    AppendLog("Server start failed!");
		ss.dwCurrentState = SERVICE_STOPPED;
		SetServiceStatus(ssh, &ss);
		return;
	}
	
	ss.dwCurrentState = SERVICE_RUNNING;
	
	if(SetServiceStatus(ssh, &ss) == false) {
		AppendLog("StartService::SetServiceStatus1 failed ("+string((uint32_t)GetLastError())+")!");
		return;
	}

	MSG msg;
	BOOL bRet;
	        
	while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
	    if(bRet == -1) {
	        // handle the error and possibly exit
	    } else {
	        if(msg.message == WM_USER+1) {
	            break;
	        } else if(msg.message == WM_TIMER) {
                if(msg.wParam == sectimer) {
                    ServerOnSecTimer();
                } else if(msg.wParam == srvLoopTimer) {
                    srvLoop->Looper();
                } else if(msg.wParam == regtimer) {
                    ServerOnRegTimer();
                } else {
                    //Must be script timer
                    ScriptOnTimer(msg.wParam);
                }
            }

	    	TranslateMessage(&msg);
	        DispatchMessage(&msg);
	    }
	}

    ExceptionHandlingUnitialize();

	ss.dwCurrentState = SERVICE_STOPPED;
	SetServiceStatus(ssh, &ss);
}
示例#24
0
文件: ntservice.cpp 项目: acplt/rte
// -------------------------------------------------------------------------
//
void KsNtServiceServer::serviceMain(int argc, char **argv)
{
    //
    // First, create some signaling objects. The _one_shot_event signals
    // the serviceRun() task that it should wake up and iterate once again,
    // thus spinning up the KS server, and process requests. The next event,
    // _service_done_event, signals, that the whole service task (executable)
    // is now ready to cease.
    //
    _service_done_event = CreateEvent(0, FALSE, FALSE, 0);
    _one_shot_event     = CreateEvent(0, FALSE, FALSE, 0);
    if ( !_service_done_event || !_one_shot_event ) {
        lastError("Can't initialize signaling mechanism");
    }
    //
    // Next, register the service controller. Remember, that only after we've
    // done this, we can report the service status to the service manager.
    //
    _service_status_handle = RegisterServiceCtrlHandler(
                                 (LPCTSTR) _service_name,
                                 (LPHANDLER_FUNCTION) ks_c_serviceController);
    if ( !_service_status_handle ) {
        lastError("Can't register service control handler");
        return;
    }
    //
    // Next, we ask the developer for a KS server object, which will be
    // subsequently used within the real workhorse thread.
    //
    reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, _create_to);
    _my_server = createServer((int) argc, (char **) argv);
    if ( !_is_ok || (_my_server == 0) || !_my_server->isOk() ) {
    	_is_ok = false;
        PltLog::Error("abnormal service termination");
        return;
    }
    verbose("Created server object successfully");
    reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2, _spinup_to);
    //
    // We must use the apropriate function from the C++ RTL here, as we will
    // otherwise get memory leaks. As if NT wouldn't be the biggest memory
    // leak ever created by menkind...
    //
#if PLT_COMPILER_MSVC
    _workhorse_thread = (HANDLE) _beginthread(
        (void (*)(void *)) ks_c_serviceRun,    // entry point of new thread
        0,                                     // stack size (default)
        0);                                    // arguments (none)
#else
# if PLT_COMPILER_BORLAND
    _workhorse_thread = (HANDLE) _beginthreadNT(
        (void (*)(void *)) ks_c_serviceRun, // entry point of new thread
        32768,                           // initial stack size
        0,                               // no arguments to pass to thread
        0,                               // no security, as NT hasn't one...
        0,                               // spin up thread immediately
        &_workhorse_thread_id);
# else
#  error "Don't know how to start threads"
# endif
#endif

    if ( _workhorse_thread <= 0) {
    	_is_ok = false;
        PltLog::Error("Can't start service thread");
        return;
    }
    verbose("Started service thread");
    //
    // Gosh! Finally, we're up and running. Yeah, I can't believe it!
    //
    reportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
    if ( WaitForSingleObject(_service_done_event, INFINITE) !=
            WAIT_OBJECT_0 ) {
        PltLog::Warning("\"Service Done\" signaling failed");
    }
    verbose("Service thread woken up");
    if ( !TerminateThread(_workhorse_thread, 0) ) {
    	lastError("Can't terminate service thread");
    }
    if ( _my_server ) {
        delete _my_server; _my_server = 0;
    }
    //
    // Simply terminate. This will throw us back to the main thread.
    //
    reportServiceStatus(SERVICE_STOPPED,
                        _service_status.dwWin32ExitCode,
                        _service_status.dwServiceSpecificExitCode, 0, 0);
} // KsNtServiceServer::serviceMain
示例#25
0
文件: service.c 项目: ashokez/zebedee
VOID
svcMain(DWORD argc, LPTSTR *argv)
{
    DWORD   wait;


    /* Register the control handler */

    SvcStatusHandle = RegisterServiceCtrlHandler(TEXT(SvcName),
						 (LPHANDLER_FUNCTION)svcControl);
    if (!SvcStatusHandle)
    {
	message(0, 0, "failed to register service control handler");
	goto finish;
    }

    /* Initialise static service status values */

    SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    SvcStatus.dwServiceSpecificExitCode = 0;

    /* Report to SCM */

    if (!svcReport(SERVICE_START_PENDING,   /* Service state */
		   NO_ERROR,		    /* Exit code */
		   1,			    /* Checkpoint number */
		   5000))		    /* Wait hint -- 5 secs */
    {
	message(0, 0, "failed to report status to SCM");
	goto finish;
    }

    /*
    ** Create the "stop event" object. The arguments indicate a manually
    ** reset event whose initial state is unset.
    */

    if ((SvcFinishEvent = CreateEvent(NULL, 1, 0, NULL)) == NULL)
    {
	goto finish;
    }

    /* Report next checkpoint to SCM */

    if (!svcReport(SERVICE_START_PENDING, NO_ERROR, 2, 5000))
    {
	message(0, 0, "failed to report status to SCM");
	goto finish;
    }

    /* Start the worker thread */

    SvcThreadHandle = (HANDLE)CreateThread(NULL, 65536, SvcFunction, SvcArg, 0, NULL);
    if (!SvcThreadHandle)
    {
	message(0, 0, "failed to create worker thread");
	goto finish;
    }

    /* Report all systems GO! */

    if (!svcReport(SERVICE_RUNNING, NO_ERROR, 0, 0))
    {
	message(0, 0, "failed to report status to SCM");
        goto finish;
    }

    /* Wait until SvcFinishEvent is set */

    wait = WaitForSingleObject(SvcFinishEvent, INFINITE);

finish:
    if (SvcFinishEvent != NULL)
    {
	CloseHandle(SvcFinishEvent);
    }

    /* Report to SCM if possible */

    if (SvcStatusHandle != 0)
    {
	svcReport(SERVICE_STOPPED, SvcError, 0, 0);
    }

    return;
}
示例#26
0
/** This callback is called by windows when the service is started */
VOID ServiceMain(DWORD argc, LPCSTR *argv)
{
	g_ServiceStatusHandle = RegisterServiceCtrlHandler(TEXT("InspIRCd"), (LPHANDLER_FUNCTION)ServiceCtrlHandler);
	if( !g_ServiceStatusHandle )
		return;

	g_ServiceStatus.dwCheckPoint = 1;
	g_ServiceStatus.dwControlsAccepted = 0;
	g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	g_ServiceStatus.dwWaitHint = 5000;
	g_ServiceStatus.dwWin32ExitCode = NO_ERROR;
	g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;

	if( !SetServiceStatus( g_ServiceStatusHandle, &g_ServiceStatus ) )
		return;

	char szModuleName[MAX_PATH];
	if(GetModuleFileNameA(NULL, szModuleName, MAX_PATH))
	{
		if(!argc)
			argc = 1;

		g_ServiceData.argc = argc;

		// Note: since this memory is going to stay allocated for the rest of the execution,
		//		 it doesn't make sense to free it, as it's going to be "freed" on process termination
		try {
			g_ServiceData.argv = new char*[argc];

			uint32_t allocsize = strnlen_s(szModuleName, MAX_PATH) + 1;
			g_ServiceData.argv[0] = new char[allocsize];
			strcpy_s(g_ServiceData.argv[0], allocsize, szModuleName);

			for(uint32_t i = 1; i < argc; i++)
			{
				allocsize = strnlen_s(argv[i], MAX_PATH) + 1;
				g_ServiceData.argv[i] = new char[allocsize];
				strcpy_s(g_ServiceData.argv[i], allocsize, argv[i]);
			}

			*(strrchr(szModuleName, '\\') + 1) = NULL;
			SetCurrentDirectoryA(szModuleName);

			HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkerThread, NULL, 0, NULL);
			if (hThread != NULL)
			{
				WaitForSingleObject(hThread, INFINITE);
				CloseHandle(hThread);
			}
		}
		catch(...)
		{
			g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
			g_ServiceStatus.dwWin32ExitCode = ERROR_OUTOFMEMORY;
			SetServiceStatus( g_ServiceStatusHandle, &g_ServiceStatus );
		}
	}
	if(g_ServiceStatus.dwCurrentState == SERVICE_STOPPED)
		return;

	g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
	g_ServiceStatus.dwWin32ExitCode = GetLastError();
	SetServiceStatus( g_ServiceStatusHandle, &g_ServiceStatus );
}
示例#27
0
    /*
     * ServiceMain function.
     */
VOID WINAPI
ServiceMain (DWORD argc, LPTSTR argv[])
{
  SECURITY_ATTRIBUTES SecurityAttributes;
  unsigned threadId;

  /*
   * Input arguments
   */
  DWORD ArgCount = 0;
  LPTSTR *ArgArray = NULL;
  TCHAR szRegKey[512];
  HKEY hParamKey = NULL;
  DWORD TotalParams = 0;
  DWORD i;
  InputParams ThreadInputParams;

  /*
   * Build the Input parameters to pass to worker thread 
   */

  /*
   * SCM sends Service Name as first arg, increment to point
   * arguments user specified while starting control agent
   */

  /*
   * Read registry parameter 
   */
  ArgCount = 1;

  /*
   * Create registry key path 
   */
  _sntprintf (szRegKey, CountOf(szRegKey), _T("%s%s\\%s"),
	     _T ("SYSTEM\\CurrentControlSet\\Services\\"), app_name_long,
	     _T("Parameters"));
  if (RegOpenKeyEx
      (HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ALL_ACCESS, &hParamKey) == ERROR_SUCCESS)
    {

      /*
       * Read startup configuration information 
       */
      /*
       * Find number of subkeys inside parameters 
       */
      if (RegQueryInfoKey (hParamKey, NULL, NULL, 0,
	   NULL, NULL, NULL, &TotalParams,
	   NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
	{
	  if (TotalParams != 0)
	    {
	      ArgCount += TotalParams;

	      /*
	       * Allocate memory to hold strings 
	       */
	      ArgArray = calloc(ArgCount, sizeof(ArgArray[0]));
              if (ArgArray == 0)
                {
                  WriteToEventLog (EVENTLOG_ERROR_TYPE,
		       _T ("Resource failure"));
                  return;
                }

	      /*
	       * Copy first argument 
	       */
	      ArgArray[0] = _tcsdup (argv[0]);
	      for (i = 1; i <= TotalParams; i++)
		{
                  DWORD dwErrorcode;
                  DWORD nSize;
                  DWORD nRegkeyType;
                  TCHAR *szValue;

		  /*
		   * Create Subkey value name 
		   */
		  _sntprintf (szRegKey, CountOf(szRegKey), _T("%s%d"), _T("Param"), i);

		  /*
		   * Query subkey.
		   */
		  nSize = 0;
		  dwErrorcode = RegQueryValueEx(hParamKey, szRegKey, NULL,
                                                &nRegkeyType, NULL, &nSize);
                  if (dwErrorcode == ERROR_SUCCESS) {
                    if (nRegkeyType == REG_SZ || nRegkeyType == REG_EXPAND_SZ) {
                      szValue = malloc(nSize + sizeof(szValue[0]));
                      if (szValue) {
		        dwErrorcode = RegQueryValueEx(hParamKey, szRegKey, NULL,
                                                      &nRegkeyType, (LPBYTE)szValue, &nSize);
                        if (dwErrorcode == ERROR_SUCCESS) {
                          szValue[nSize] = 0;
                          ArgArray[i] = szValue;
                        } else {
                          free(szValue);
                          WriteToEventLog(EVENTLOG_ERROR_TYPE, _T("Querying registry key %s failed: error code %ld"), szRegKey, dwErrorcode);
                        }
                      } else
                        WriteToEventLog(EVENTLOG_ERROR_TYPE, _T("Querying registry key %s failed: out of memory"), szRegKey);
                    } else
                      WriteToEventLog(EVENTLOG_ERROR_TYPE, _T("Type %ld of registry key %s is incorrect"), nRegkeyType, szRegKey);
                  } else
                    WriteToEventLog(EVENTLOG_ERROR_TYPE, _T("Querying registry key %s failed: error code %ld"), szRegKey, dwErrorcode);

                  if (!ArgArray[i]) {
                    TotalParams = ArgCount = i;
                    break;
                  }
		}
	    }
	}
      RegCloseKey (hParamKey);
    }
  if (ArgCount == 1)
    {

      /*
       * No startup args are given 
       */
      ThreadInputParams.Argc = argc;
      ThreadInputParams.Argv = argv;
    }

  else
    {
      ThreadInputParams.Argc = ArgCount;
      ThreadInputParams.Argv = ArgArray;
    }

  /*
   * Register Service Control Handler 
   */
  hServiceStatus = RegisterServiceCtrlHandler (app_name_long, ControlHandler);
  if (hServiceStatus == 0)
    {
      WriteToEventLog (EVENTLOG_ERROR_TYPE,
		       _T ("RegisterServiceCtrlHandler failed"));
      return;
    }

  /*
   * Update the service status to START_PENDING.
   */
  UpdateServiceStatus (SERVICE_START_PENDING, NO_ERROR, SCM_WAIT_INTERVAL);

  /*
   * Start the worker thread, which does the majority of the work .
   */
  TRY
  {
    if (SetSimpleSecurityAttributes (&SecurityAttributes) == FALSE)
      {
	WriteToEventLog (EVENTLOG_ERROR_TYPE,
			 _T ("Couldn't init security attributes"));
	LEAVE;
      }
    hServiceThread =
      (void *) _beginthreadex (&SecurityAttributes, 0,
			       ThreadFunction,
			       (void *) &ThreadInputParams, 0, &threadId);
    if (hServiceThread == NULL)
      {
	WriteToEventLog (EVENTLOG_ERROR_TYPE, _T ("Couldn't start worker thread"));
	LEAVE;
      }

    /*
     * Set service status to SERVICE_RUNNING.
     */
    UpdateServiceStatus (SERVICE_RUNNING, NO_ERROR, SCM_WAIT_INTERVAL);

    /*
     * Wait until the worker thread finishes.
     */
    WaitForSingleObject (hServiceThread, INFINITE);
  }
  FINALLY
  {
    /*
     * Release resources 
     */
    UpdateServiceStatus (SERVICE_STOPPED, NO_ERROR, SCM_WAIT_INTERVAL);
    if (hServiceThread)
      CloseHandle (hServiceThread);
    FreeSecurityAttributes (&SecurityAttributes);

    /*
     * Free allocated argument list 
     */
    if (ArgCount > 1 && ArgArray != NULL)
      {
	/*
	 * Free all strings 
	 */
	for (i = 0; i < ArgCount; i++)
	  {
	    free (ArgArray[i]);
	  }
	free (ArgArray);
      }
  }
}
/* Registers the call-back and configures the actions in case of a failure
 * with the Windows services manager. */
void
service_start(int *argcp, char **argvp[])
{
    int argc = *argcp;
    char **argv = *argvp;
    int i;
    SERVICE_TABLE_ENTRY service_table[] = {
        {(LPTSTR)program_name, (LPSERVICE_MAIN_FUNCTION)main},
        {NULL, NULL}
    };

    /* 'detached' is 'false' when service_start() is called the first time.
     * It is 'true', when it is called the second time by the Windows services
     * manager. */
    if (detached) {
        init_service_status();

        wevent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!wevent) {
            char *msg_buf = ovs_lasterror_to_string();
            VLOG_FATAL("Failed to create a event (%s).", msg_buf);
        }

        poll_fd_wait_event(0, wevent, POLLIN);

        /* Register the control handler. This function is called by the service
         * manager to stop the service. */
        hstatus = RegisterServiceCtrlHandler(program_name,
                                         (LPHANDLER_FUNCTION)control_handler);
        if (!hstatus) {
            char *msg_buf = ovs_lasterror_to_string();
            VLOG_FATAL("Failed to register the service control handler (%s).",
                        msg_buf);
        }

        if (monitor) {
            set_config_failure_actions();
        }

        /* When the service control manager does the call back, it does not
         * send the same arguments as sent to the main function during the
         * service start. So, use the arguments passed over during the first
         * time. */
        *argcp = sargc;
        *argvp = *sargvp;

        /* XXX: Windows implementation cannot have a unixctl commands in the
        * traditional sense of unix domain sockets. If an implementation is
        * done that involves 'unixctl' vlog commands the following call is
        * needed to make sure that the unixctl commands for vlog get
        * registered in a daemon, even before the first log message. */
        vlog_init();

        return;
    }

    assert_single_threaded();

    /* A reference to arguments passed to the main function the first time.
     * We need it after the call-back from service control manager. */
    sargc = argc;
    sargvp = argvp;

    /* We are only interested in the '--service' and '--service-monitor'
     * options before the call-back from the service control manager. */
    for (i = 0; i < argc; i ++) {
        if (!strcmp(argv[i], "--service")) {
            detach = true;
        } else if (!strcmp(argv[i], "--service-monitor")) {
            monitor = true;
        }
    }

    /* If '--service' is not a command line option, run in foreground. */
    if (!detach) {
        return;
    }

    /* If we have been configured to run as a service, then that service
     * should already have been created either manually or through a start up
     * script. */
    check_service();

    detached = true;

    /* StartServiceCtrlDispatcher blocks and returns after the service is
     * stopped. */
    if (!StartServiceCtrlDispatcher(service_table)) {
        char *msg_buf = ovs_lasterror_to_string();
        VLOG_FATAL("Failed at StartServiceCtrlDispatcher (%s)", msg_buf);
    }
    exit(0);
}
示例#29
0
文件: repl.c 项目: mingpen/OpenNT
VOID
ReplMain(
    IN DWORD dwNumServicesArgs,
    IN LPTSTR *lpServiceArgVectors
    )
/*++

Routine Description:

    Talk to service controller, read registry, and change role (which
    starts import and/or export parts).

Arguments:

    Ignored.  (Required by service controller interface.)

Return Value:

    None.

--*/

{
    NET_API_STATUS ApiStatus;
    BOOL LockedConfigData = FALSE;
    DWORD NewRole;

    UNREFERENCED_PARAMETER( dwNumServicesArgs );
    UNREFERENCED_PARAMETER( lpServiceArgVectors );

    IF_DEBUG( MAJOR ) {
        NetpKdPrint(( PREFIX_REPL
                "**************************** STARTING REPL "
                "****************************\n" ));
    }

    // DbgBreakPoint();


    // Register control routine.
    // This must be done before any calls to ReportStatus().

    ReplGlobalServiceHandle = RegisterServiceCtrlHandler(
                    (LPTSTR) SERVICE_REPL,
                    ReplControlRoutine );

    if (ReplGlobalServiceHandle == (SERVICE_STATUS_HANDLE) NULL) {

        // can't start service

        NetpKdPrint(( PREFIX_REPL "can't start repl service, "
                "RegisterServiceCtrlHandler is in error.\n" ));

        // Haven't done anything to clean up, so don't.
        return;

    }

    ReportStatus(
            SERVICE_START_PENDING,
            NO_ERROR,
            REPL_WAIT_HINT,
            1 );                        // checkpoint


    // initialize global data

    ApiStatus = ReplInit();
    if (ApiStatus != NO_ERROR) {

        goto Cleanup;

    }

    ReportStatus(
            SERVICE_START_PENDING,
            NO_ERROR,
            REPL_WAIT_HINT,
            2 );                        // checkpoint


    // Read config data from registry.  We just read the stuff controlling the
    // service as a whole here; the client and master threads each read their
    // own config data as well.

    ApiStatus = ReplConfigRead(
            NULL,       // no server name
            & NewRole,
            ReplConfigExportPath,
            &ReplConfigExportList,      // Alloc and set ptr.
            ReplConfigImportPath,
            &ReplConfigImportList,      // Alloc and set ptr.
            ReplConfigLogonUserName,
            & ReplConfigInterval,
            & ReplConfigPulse,
            & ReplConfigGuardTime,
            & ReplConfigRandom );
    if (ApiStatus != NO_ERROR) {

        goto Cleanup;

    }

#if DBG
    {
        LPNET_CONFIG_HANDLE SectionHandle = NULL;
        LPWSTR              ValueT = NULL;

        ApiStatus = NetpOpenConfigData(
                &SectionHandle,
                NULL,                           // no server name.
                (LPTSTR) SECT_NT_REPLICATOR,    // section name
                TRUE );                         // we only want readonly access
        NetpAssert( ApiStatus == NO_ERROR );

        ApiStatus = NetpGetConfigValue (
                SectionHandle,
                (LPTSTR) REPL_KEYWORD_DBFLAG,
                &ValueT );
        (VOID) NetpCloseConfigData( SectionHandle );
        if (ApiStatus == NO_ERROR) {

            NetpAssert( ValueT != NULL );
            ReplGlobalTrace = NetpAtoX( ValueT );
            (VOID) NetApiBufferFree( ValueT );

        } else if (ApiStatus == NERR_CfgParamNotFound) {

            //
            // copy default value in here.
            //

            // ReplGlobalTrace = 0;
        } else {
            NetpKdPrint(( PREFIX_REPL
                    "ReplMain: unexpected error " FORMAT_API_STATUS
                    " from NetpGetConfigValue.\n", ApiStatus ));
            // Probably harmless, so let's continue...
        }
    }
#endif // DBG

    //
    // Make sure role in registry is allowed with current product type.
    //
    if ( !ReplConfigIsRoleAllowed( NULL, NewRole ) ) {
        // BUGBUG: Log this!
        NetpKdPrint(( PREFIX_REPL "Role inconsistent with product type; "
                " assuming role of " FORMAT_DWORD ".\n", REPL_ROLE_IMPORT ));

        NewRole = REPL_ROLE_IMPORT;

        // Update registry so we don't get this every time.
        ApiStatus = ReplConfigWrite(
                NULL,       // no server name
                NewRole,
                ReplConfigExportPath,
                ReplConfigExportList,
                ReplConfigImportPath,
                ReplConfigImportList,
                ReplConfigLogonUserName,
                ReplConfigInterval,
                ReplConfigPulse,
                ReplConfigGuardTime,
                ReplConfigRandom );
        if (ApiStatus != NO_ERROR) {
            goto Cleanup;
        }
    }


    ReportStatus(
            SERVICE_START_PENDING,
            NO_ERROR,
            REPL_WAIT_HINT,
            3 );                        // checkpoint

    // ReplChangeRole assumes caller has exclusive lock on ReplConfigLock.
    ACQUIRE_LOCK( ReplConfigLock );
    LockedConfigData = TRUE;

    //
    // Change the role to the one.  This is where most of the work gets done,
    // like starting other threads and so on.  This is also where ReplConfigRole
    // gets set.  Also, the RPC server will be started or stopped as necessary.
    // Last and not least, ReplChngRole() will inform the service controller.
    // NOTE: ReplChangeRole assumes caller has exclusive lock on ReplConfigLock.
    //

    ApiStatus = ReplChangeRole( NewRole );

    if (ApiStatus != NO_ERROR) {
        goto Cleanup;
    }

    IF_DEBUG(REPL) {
        NetpKdPrint(( PREFIX_REPL "ReplMain: changed role OK.\n" ));
    }

    if (LockedConfigData) {
        RELEASE_LOCK( ReplConfigLock );
        LockedConfigData = FALSE;
    }

    IF_DEBUG( REPL ) {
        NetpKdPrint(( PREFIX_REPL "ReplMain: exiting thread!!!!!!!!!!!!!!\n" ));
    }

    //
    // That's all, folks.  When somebody decides to stop the service,
    // ReplControlRoutine will create the Stopper and Staller threads to do it.
    //

    return;


Cleanup :

    NetpKdPrint(( PREFIX_REPL
            "ReplMain: forced to cleanup; shutting down svc...; status "
            FORMAT_API_STATUS "\n", ApiStatus ));

    ReplGlobalUninstallUicCode = ApiStatus;  // So service ctrl gets told.

    if ( !LockedConfigData ) {
        // Get lock for ReplChangeRole().
        ACQUIRE_LOCK( ReplConfigLock );
        LockedConfigData = TRUE;
    }

    //
    // Make sure nothing is left running...
    //
    // Change role back to stopped, and do all other cleanup.
    // NOTE: ReplChangeRole assumes caller has exclusive lock on ReplConfigLock.
    (VOID) ReplChangeRole( REPL_ROLE_STOPPED );

    if (LockedConfigData) {
        RELEASE_LOCK( ReplConfigLock );
    }

    ReplCleanup();

    // Report status.  This needs ReplGlobalServiceHandle one last time.

    ReportStatus(
            SERVICE_STOPPED,
            ReplGlobalUninstallUicCode,
            0,                          // wait hint
            0 );                        // checkpoint

    // BUGBUG: Close ReplGlobalServiceHandle here someday?

    IF_DEBUG( MAJOR ) {
        NetpKdPrint(( PREFIX_REPL
                "**************************** ENDING REPL "
                "****************************\n" ));
    }

    return;

} // ReplMain
示例#30
-1
/* service_main */
static VOID WINAPI service_main(DWORD argc, LPTSTR *argv) {
    config_t        conf;
    void*           net;
    void*           threads;
    void*           pipe;

    h_service = RegisterServiceCtrlHandler(LDMSVC_SERVICE_NAME, handler);
    if(h_service == NULL) {
        return;
    }

    set_state1(SERVICE_START_PENDING);        // SERVICE_START_PENDING

    // open the heap
    if(!heap_start()) {
        dout("Failed to create the heap\n");
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // parse configuration
    if(!config_parse_args(&conf, argc, argv)) {
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    if(0) {
        dout(va("PORT: %u\n", conf.port));
        dout(va("PIPE: %s\n", conf.pipe));
        dout(va("MAXC: %u\n", conf.maxconn));
    }

    // open network
    if((net = net_start()) == NULL) {
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // open the pipe
    if((pipe = pipe_start(conf.pipe)) == NULL) {
        net_stop(net);
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // connect the pipe
    if(!pipe_open(pipe)) {
        pipe_stop(pipe);
        net_stop(net);
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // start threads
    if((threads = threads_start(net, pipe, conf.maxconn)) == NULL) {
        pipe_stop(pipe);
        net_stop(net);
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    set_state1(SERVICE_RUNNING);              // SERVICE_RUNNING

    while(svc_state == SERVICE_RUNNING) {
        if(!net_is_ready(net)) {
            net_bind(net, NULL, conf.port);
        }

        if(!threads_think(threads)) {
            break;
        }

        Sleep(1);
    }

    set_state1(SERVICE_STOP_PENDING);         // SERVICE_STOP_PENDING

    // close everything here
    threads_stop(threads);
    pipe_stop(pipe);
    net_stop(net);
    heap_stop();

    set_state2(SERVICE_STOPPED, 0);           // SERVICE_STOPPED
}