📄 ntservice.c
字号:
/* * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: ntservice.c,v 1.3.2.1.10.3 2004/03/08 04:04:22 marka Exp $ */#include <config.h>#include <stdio.h>#include <isc/app.h>#include <isc/log.h>#include <named/globals.h>#include <named/ntservice.h>#include <named/main.h>#include <named/server.h>/* Handle to SCM for updating service status */static SERVICE_STATUS_HANDLE hServiceStatus = 0;static BOOL foreground = FALSE;static char ConsoleTitle[128];/* * Forward declarations */void ServiceControl(DWORD dwCtrlCode);void GetArgs(int *, char ***, char ***);int main(int, char *[], char *[]); /* From ns_main.c *//* * Here we change the entry point for the executable to bindmain() from main() * This allows us to invoke as a service or from the command line easily. */#pragma comment(linker, "/entry:bindmain")/* * This is the entry point for the executable * We can now call main() explicitly or via StartServiceCtrlDispatcher() * as we need to. */int bindmain(){ int rc, i = 1; int argc; char **envp, **argv; /* * We changed the entry point function, so we must initialize argv, * etc. ourselves. Ick. */ GetArgs(&argc, &argv, &envp); /* Command line users should put -f in the options */ while (argv[i]) { if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "-g")) { foreground = TRUE; break; } i++; } if (foreground) { /* run in console window */ exit(main(argc, argv, envp)); } else { /* Start up as service */ char *SERVICE_NAME = BIND_SERVICE_NAME; SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT(SERVICE_NAME), (LPSERVICE_MAIN_FUNCTION)main }, { NULL, NULL } }; rc = StartServiceCtrlDispatcher(dispatchTable); if (!rc) { fprintf(stderr, "Use -f to run from the command line.\n"); exit(GetLastError()); } } exit(0);}/* * Initialize the Service by registering it. */voidntservice_init() { if (!foreground) { /* Register handler with the SCM */ hServiceStatus = RegisterServiceCtrlHandler(BIND_SERVICE_NAME, (LPHANDLER_FUNCTION)ServiceControl); if (!hServiceStatus) { ns_main_earlyfatal( "could not register service control handler"); UpdateSCM(SERVICE_STOPPED); exit(1); } UpdateSCM(SERVICE_RUNNING); } else { strcpy(ConsoleTitle, "BIND Version "); strcat(ConsoleTitle, VERSION); SetConsoleTitle(ConsoleTitle); }}voidntservice_shutdown() { UpdateSCM(SERVICE_STOPPED);}/* * Routine to check if this is a service or a foreground program */BOOLntservice_isservice() { return(!foreground);}/* * ServiceControl(): Handles requests from the SCM and passes them on * to named. */voidServiceControl(DWORD dwCtrlCode) { /* Handle the requested control code */ switch(dwCtrlCode) { case SERVICE_CONTROL_INTERROGATE: UpdateSCM(0); break; case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: ns_server_flushonshutdown(ns_g_server, ISC_TRUE); isc_app_shutdown(); UpdateSCM(SERVICE_STOPPED); break; default: break; }}/* * Tell the Service Control Manager the state of the service. */void UpdateSCM(DWORD state) { SERVICE_STATUS ss; static DWORD dwState = SERVICE_STOPPED; if (hServiceStatus) { if (state) dwState = state; memset(&ss, 0, sizeof(SERVICE_STATUS)); ss.dwServiceType |= SERVICE_WIN32_OWN_PROCESS; ss.dwCurrentState = dwState; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ss.dwCheckPoint = 0; ss.dwServiceSpecificExitCode = 0; ss.dwWin32ExitCode = NO_ERROR; ss.dwWaitHint = dwState == SERVICE_STOP_PENDING ? 10000 : 1000; if (!SetServiceStatus(hServiceStatus, &ss)) { ss.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hServiceStatus, &ss); } }}/* * C-runtime stuff used to initialize the app and * get argv, argc, envp. */typedef struct { int newmode;} _startupinfo;_CRTIMP void __cdecl __set_app_type(int);_CRTIMP void __cdecl __getmainargs(int *, char ***, char ***, int, _startupinfo *);void __cdecl _setargv(void);#ifdef _M_IX86/* Pentium FDIV adjustment */extern int _adjust_fdiv;extern int * _imp___adjust_fdiv;/* Floating point precision */extern void _setdefaultprecision();#endifextern int _newmode; /* malloc new() handler mode */extern int _dowildcard; /* passed to __getmainargs() */typedef void (__cdecl *_PVFV)(void);extern void __cdecl _initterm(_PVFV *, _PVFV *);extern _PVFV *__onexitbegin;extern _PVFV *__onexitend;extern _CRTIMP char **__initenv;/* * Do the work that mainCRTStartup() would normally do */void GetArgs(int *argc, char ***argv, char ***envp){ _startupinfo startinfo; /* * Set the app type to Console (check CRT/SRC/INTERNAL.H: * #define _CONSOLE_APP 1) */ __set_app_type(1); /* Mark this module as an EXE file */ __onexitbegin = __onexitend = (_PVFV *)(-1); startinfo.newmode = _newmode; __getmainargs(argc, argv, envp, _dowildcard, &startinfo); __initenv = *envp;#ifdef _M_IX86 _adjust_fdiv = * _imp___adjust_fdiv; _setdefaultprecision();#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -