Beispiel #1
0
//
//	サービスメイン処理
//
void service_main(void)
{
	PROCESS_INFORMATION pi;

	service_handle = RegisterServiceCtrlHandler(service_name,
	                               (LPHANDLER_FUNCTION)service_control_handler);
	if(service_handle != 0) {
		send_status_to_scm(SERVICE_START_PENDING, 0, 1);

		send_status_to_scm(SERVICE_RUNNING, 0, 0);
		// プログラムを起動する。
		if(execute_process(exe_name, option_name, &pi)) {
			// 2009/3/26
			shutdown_flag = 0;

			process_id = pi.dwProcessId;
			send_status_to_scm(SERVICE_RUNNING, 0, 0);

			// サービスの終了で抜ける
			while(1) {
		    	if(WaitForSingleObject(pi.hProcess, 0) != WAIT_TIMEOUT) {
					// 2001/11/9
					CloseHandle(pi.hThread);
					CloseHandle(pi.hProcess);
					// 2009/3/26
					if(!retry_flag || shutdown_flag) {
						break;
					} else {
						if(execute_process(exe_name, option_name, &pi)) {
							process_id = pi.dwProcessId;
						} else {
							break;
						}
					}
				}
				Sleep(100);
			}
		}
// 2011/9/1 kimukou.buzz
		//if(end_pattern == END_CTRL_BREAK) {
		if(end_pattern == END_CTRL_BREAK || end_pattern == END_CTRL_C) {
// 2011/9/1 kimukou.buzz
			FreeConsole();
		}
		CloseHandle(mutex);
	}
	send_status_to_scm(SERVICE_STOPPED, 0, 0);
}
Beispiel #2
0
//
//	サービス制御要求処理
//	in: control .. SERVICE_CONTROL_STOP, SERVICE_CONTROL_SHUTDOWN で終了処理
//
void service_control_handler(int control)
{
	switch(control) {
		case SERVICE_CONTROL_STOP:
		case SERVICE_CONTROL_SHUTDOWN:
			// 2009/3/26
			shutdown_flag = 1;

			send_status_to_scm(SERVICE_STOP_PENDING, 0, 1);
			if(end_pattern == END_CTRL_BREAK) {
				GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, process_id);
// 2011/9/1 kimukou.buzz
			}else if(end_pattern == END_CTRL_C) {
				GenerateConsoleCtrlEvent(CTRL_C_EVENT, process_id);
// 2011/9/1 kimukou.buzz
			} else {
				EnumWindows(EnumWindowsProc, end_pattern);
			}
			send_status_to_scm(SERVICE_STOPPED, 0, 0);
			break;
	}
}
      // handle an error from service_main by cleaning up
      // and telling SCM that the service didn't start.
      void terminate(DWORD error)
      {
      	if(error == 0 && terminate_code_ != 0)
         {
         	 error = terminate_code_;
         }

      	stop();

         csbl::shared_ptr<status> st =
            context_.find<status>();
         csbl::shared_ptr<wait_for_termination_request> tr =
            context_.find<wait_for_termination_request>();

         if(st) st->state(status::stopped);
         if(tr) tr->proceed();

         launch_thread_->join();

         // Send a message to the scm to tell about stopage
         send_status_to_scm(SERVICE_STOPPED, 0, 0, error);

         // Do not need to close serviceStatusHandle
      }
      // 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_);
      }
      // Handle SCM signals
      void service_handler(DWORD dwOpcode)
      {
         csbl::shared_ptr<status> st =
            context_.find<status>();

         switch (dwOpcode)
         {
            case SERVICE_CONTROL_STOP:
            {
               if(!stop())
                  // don't accept, returns the service
                  // could not accept control messages
                  return;

               request_terminate(0);
            }
            break;
            case SERVICE_CONTROL_SHUTDOWN:
            {
               stop();
               request_terminate(0);
            }
            case SERVICE_CONTROL_PAUSE:
            {
               if(!pause())
                  // don't accept, returns the service
                  // could not accept control messages
                  return;

               if (!send_status_to_scm(SERVICE_PAUSE_PENDING, 1, 1000))
               {
                  request_terminate(GetLastError());
                  return;
               }

               if(st) st->state(status::paused);

               if (!send_status_to_scm(SERVICE_PAUSED, 0, 0))
               {
                  request_terminate(GetLastError());
                  return;
               }
            }
            break;

            case SERVICE_CONTROL_CONTINUE:
            {
               if(!resume())
                  // don't accept, returns the service
                  // could not accept control messages
                  return;

               if (!send_status_to_scm(SERVICE_CONTINUE_PENDING, 1, 1000))
               {
                  request_terminate(GetLastError());
                  return;
               }

               if(st) st->state(status::running);

               if (!send_status_to_scm(SERVICE_RUNNING, 0, 0))
               {
               	request_terminate(GetLastError());
                  return;
               }
            }
            break;

            case SERVICE_CONTROL_INTERROGATE:
            {
               // Nothing here!
            }
            break;
         }
      }