예제 #1
0
//callbacks
static
VOID WINAPI _Handler(_In_ DWORD dwOpcode) throw()
{
	switch( dwOpcode ) {
	case SERVICE_CONTROL_STOP:
		// stop
		_set_service_status(SERVICE_STOP_PENDING);
		::PostThreadMessage(g_dwThreadID, WM_QUIT, 0, 0);  //no check
		break;
	case SERVICE_CONTROL_PAUSE:
		// pause
		break;
	case SERVICE_CONTROL_CONTINUE:
		// continue
		break;
	case SERVICE_CONTROL_INTERROGATE:
		// interrogate
		break;
	case SERVICE_CONTROL_SHUTDOWN:
		// shutdown
		break;
	default:
		// UnknownRequest
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Bad service request"));
		break;
	}  //end switch
}
예제 #2
0
static
VOID WINAPI _ServiceMain(
	_In_ DWORD dwArgc,
	_In_ LPWSTR* lpszArgv) throw()
{
//Register the control request handler
	g_status.dwCurrentState = SERVICE_START_PENDING;
	g_dwThreadID = ::GetCurrentThreadId();
	g_hServiceStatus = ::RegisterServiceCtrlHandlerW(L"", _Handler);
	if( g_hServiceStatus == NULL ) {
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Handler not installed"));
		return ;
	}
	_set_service_status(SERVICE_START_PENDING);

	g_status.dwWin32ExitCode = S_OK;
	g_status.dwCheckPoint = 0;
	g_status.dwWaitHint = 0;

//command
	const_array<const_string_s> args;
	_auto_mem spArgs;
	//convert
	try {
		_cmdline_to_strings(dwArgc, lpszArgv, spArgs, args);  //may throw
	}
	catch(...) {
		_set_service_status(SERVICE_STOPPED);
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Out of memory"));
		return ;
	}

//COM
	HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if( FAILED(hr) ) {
		_set_service_status(SERVICE_STOPPED);
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Cannot initialize MTA!"));
		return ;
	}

//loop
	_os_create_thread_message_queue();  //message queue

	_set_service_status(SERVICE_RUNNING);
	report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_SUCCESS, _S("Service started/resumed"));

	service_main_loop sml;
	if( !sml.Prepare(args) ) {
		::CoUninitialize();
		_set_service_status(SERVICE_STOPPED);
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Initialize loop failed!"));
		return ;
	}

	while( true ) {
		MSG msg;
		BOOL bRet = ::PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE);
		if( bRet ) {
			bRet = ::GetMessageW(&msg, NULL, 0, 0);
			//WM_QUIT
			if( !bRet )
				break;
			::TranslateMessage(&msg);  //no check
			::DispatchMessageW(&msg);  //no check
		}
		else {
			if( !sml.OneLoop() )
				break;
			//to be continued
			thread_sleep(1);
		} //end if
	} //end while

//final
	g_status.dwWin32ExitCode = sml.Cleanup();

	::CoUninitialize();
	_set_service_status(SERVICE_STOPPED);
	report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_SUCCESS, _S("Service stopped!"));
}
예제 #3
0
파일: service_main.cpp 프로젝트: ZJUGKC/GKC
int main(int argc, char *argv[], char *envp[])
{
//start
	//no check
	::signal(SIGTTOU, SIG_IGN);
	::signal(SIGTTIN, SIG_IGN);
	::signal(SIGTSTP, SIG_IGN);
	::signal(SIGHUP, SIG_IGN);
	//fork
	pid_t pid = ::fork();
	if( pid == -1 ) {
		::perror("cannot fork!\n");
		exit(EXIT_FAILURE);
		//return -1;
	}
	if( pid != 0 ) {
		exit(EXIT_SUCCESS);  //parent process
		//return 0;
	}

//in child
	//setsid
	pid = ::setsid();
	if( pid == (pid_t)-1 ) {
		::perror("cannot initialize session!\n");
		return -1;
	}
	::signal(SIGHUP, SIG_IGN);

/*
//second
	//fork
	pid_t pid2 = ::fork();
	if( pid2 == -1 ) {
		::perror("cannot fork 2!\n");
		exit(EXIT_FAILURE);
		//return -1;
	}
	if( pid2 != 0 ) {
		exit(EXIT_SUCCESS);  //parent process
		//return 0;
	}
	::signal(SIGHUP, SIG_IGN);
*/

	//cwd
	if( ::chdir("/") == -1 ) {
		::perror("cannot change dir!\n");
		return -1;
	}
	//close handles
	const int c_MAXFILE = 65535;
	for( int i = 0; i < c_MAXFILE; i ++ )
		::close(i);  //no check
	//::open("/dev/null", O_RDONLY);
	//::open("/dev/null", O_RDWR);
	//::open("/dev/null", O_RDWR);
	//mask
	::umask(0);
	//signal
	::signal(SIGCHLD, SIG_IGN);  //no check

/*
	::signal(SIGINT, SIG_IGN);  //no check
	::signal(SIGWINCH, SIG_IGN);  //no check
*/

//command
	const_array<const_string_s> args;
	_auto_mem spArgs;
	//convert
	try {
		_cmdline_to_strings(argc, argv, spArgs, args);  //may throw
	}
	catch(...) {
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Out of memory!"));
		return -1;
	}

	//arrange to catch the signal
	::signal(SIGTERM, _sig_term);  //no check

//global
	//time
	time_initialize();

//loop
	report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_SUCCESS, _S("Start Service!"));
	service_main_loop sml;
	if( !sml.Prepare(args) ) {
		report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_ERROR, _S("Initialize loop failed!"));
		return -1;
	}
	while( !g_ServiceExitFlag ) {
		if( !sml.OneLoop() )
			break;
		thread_sleep(1);
	} //end while

//final
	int ret = sml.Cleanup();
	report_service_log(GKC_SERVICE_NAME, SERVICE_LOG_SUCCESS, _S("Service Stopped!"));

	return ret;
}