⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 service.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* Prevent holding open the (hidden) console */    real_exit_code = 0;    Windows9xServiceCtrlHandler(ap_control_handler, service_name);    atexit(stop_service_monitor);        /* Run the service */    globdat.exit_status = main_fn(argc, argv);    return (globdat.exit_status);}static HANDLE eventlog_pipewrite = NULL;static HANDLE eventlog_thread = NULL;int service_main(int (*main_fn)(int, char **), int argc, char **argv ){    SERVICE_TABLE_ENTRY dispatchTable[] =    {        { "", service_main_fn },        { NULL, NULL }    };    /* Prevent holding open the (nonexistant) console and allow us past     * the first NT service to parse the service's args in apache_main()      */    ap_server_argv0 = argv[0];    real_exit_code = 0;    /* keep the server from going to any real effort, since we know */    is_service = 1;    globdat.main_fn = main_fn;    globdat.connected = 1;    if(!StartServiceCtrlDispatcher(dispatchTable))    {        /* This is a genuine failure of the SCM. */        ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,                     "Error starting service control dispatcher");    }    globdat.connected = 0;    if (eventlog_pipewrite)    {        CloseHandle(eventlog_pipewrite);        WaitForSingleObject(eventlog_thread, 10000);        eventlog_pipewrite = NULL;    }    return(globdat.exit_status);}long __stdcall service_stderr_thread(LPVOID hPipe){    HANDLE hPipeRead = (HANDLE) hPipe;    HANDLE hEventSource;    char errbuf[256];    char *errmsg = errbuf;    char *errarg[9];    DWORD errlen = 0;    DWORD errres;    HKEY hk;        errarg[0] = "The Apache service named";    errarg[1] = ap_server_argv0;    errarg[2] = "reported the following error:\r\n>>>";    errarg[3] = errmsg;    errarg[4] = "<<<\r\n before the error.log file could be opened.\r\n";    errarg[5] = "More information may be available in the error.log file.";    errarg[6] = NULL;    errarg[7] = NULL;    errarg[8] = NULL;        /* What are we going to do in here, bail on the user?  not. */    if (!RegCreateKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services"                      "\\EventLog\\Application\\Apache Service", &hk))     {        /* The stock message file */        char *netmsgkey = "%SystemRoot%\\System32\\netmsg.dll";        DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |                        EVENTLOG_INFORMATION_TYPE;          RegSetValueEx(hk, "EventMessageFile", 0, REG_EXPAND_SZ,                          (LPBYTE) netmsgkey, strlen(netmsgkey) + 1);                RegSetValueEx(hk, "TypesSupported", 0, REG_DWORD,                          (LPBYTE) &dwData, sizeof(dwData));        RegCloseKey(hk);    }    hEventSource = RegisterEventSource(NULL, "Apache Service");    while (ReadFile(hPipeRead, errmsg, 1, &errres, NULL) && (errres == 1))    {        if ((errmsg > errbuf) || !isspace(*errmsg))        {            ++errlen;            ++errmsg;            if ((*(errmsg - 1) == '\n') || (errlen == sizeof(errbuf) - 1))            {                while (errlen && isspace(errbuf[errlen - 1]))                    --errlen;                errbuf[errlen] = '\0';                /* Generic message: '%1 %2 %3 %4 %5 %6 %7 %8 %9'                 * The event code in netmsg.dll is 3299                 */                ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0,                             3299, NULL, 9, 0, errarg, NULL);                errmsg = errbuf;                errlen = 0;            }        }    }    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,                 "Shut down the Service Error Event Logger.");    CloseHandle(eventlog_pipewrite);    eventlog_pipewrite = NULL;        CloseHandle(hPipeRead);    CloseHandle(eventlog_thread);    eventlog_thread = NULL;    return 0;}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 );}/* Set the service description regardless of platform. * We revert to set_service_description_string on NT/9x, the * very long way so any Apache management program can grab the * description.  This would be bad on Win2000, since it wouldn't * notify the service control manager of the name change. */static void set_service_description_string(const char *description){    char szPath[MAX_PATH];    HKEY hkey;    /* Create/Find the Service key that Monitor Applications iterate */    ap_snprintf(szPath, sizeof(szPath),                 "SYSTEM\\CurrentControlSet\\Services\\%s", globdat.name);    ap_remove_spaces(szPath, szPath);    if (RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hkey) != ERROR_SUCCESS) {        return;    }    /* Attempt to set the Description value for our service */    RegSetValueEx(hkey, "Description", 0, REG_SZ,                    (unsigned char *) description,                   strlen(description) + 1);    RegCloseKey(hkey);}char *get_service_name(char *display_name){    /* Get the service's true name from the SCM on NT/2000, since it     * can be changed by the user on 2000, especially, from the     * service control panel.  We can't trust the service name to      * match a space-collapsed display name.     */    char service_name[MAX_PATH];    if (isWindowsNT())    {        SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);        DWORD namelen = sizeof(service_name);        if (scm) {            BOOL ok = GetServiceKeyName(scm, display_name, service_name,                                         &namelen);            CloseServiceHandle(scm);            if (ok)                return strdup(service_name);        }    }    ap_remove_spaces(service_name, display_name);    return strdup(service_name);}char *get_display_name(char *service_name){    /* Get the service's display name from the SCM on NT/2000, since it     * can be changed by the user on 2000, especially, from the     * service control panel.  We can't trust the service name as     * provided by the user.     */    if (isWindowsNT())    {        char display_name[MAX_PATH];        SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);        DWORD namelen = sizeof(display_name);        if (scm) {            BOOL ok = GetServiceDisplayName(scm, service_name, display_name,                                            &namelen);            CloseServiceHandle(scm);            if (ok)                return strdup(display_name);        }    }    return service_name;}/* ChangeServiceConfig2() prototype: */typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);/* Windows 2000 alone supports ChangeServiceConfig2 in order to * register our server_version string... so we need some fixups * to avoid binding to that function if we are on WinNT/9x. * Fall back on set_service_description_string if we fail. */void service_set_status(int status){    const char *full_description;    SC_HANDLE schSCManager;    CSD_T ChangeServiceDescription;    HANDLE hwin2000scm;    BOOL ret = 0;    /* Nothing to do if we are a console     */    if (!is_service)        return;    ReportStatusToSCMgr(status, NO_ERROR, 3000);    if (status != SERVICE_RUNNING)        return;    /* Time to fix up the description, upon each successful restart     */    full_description = ap_get_server_version();    hwin2000scm = GetModuleHandle("ADVAPI32.DLL");    if (!hwin2000scm) {        set_service_description_string(full_description);        return;    }    ChangeServiceDescription = (CSD_T) GetProcAddress(hwin2000scm,                                                       "ChangeServiceConfig2A");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -