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

📄 service.c

📁 apache简化版
💻 C
字号:
#ifdef WIN32#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <process.h>#include <direct.h>#include "httpd.h"#include "http_conf_globals.h"#include "http_log.h"#include "http_main.h"#include "multithread.h"#include "service.h"#include "registry.h"static struct{    int (*main_fn)(int, char **);    event *stop_event;    int connected;    SERVICE_STATUS_HANDLE hServiceStatus;    char *name;    int exit_status;    SERVICE_STATUS ssStatus;    FILE *logFile;} globdat;static void WINAPI service_main_fn(DWORD, char **);static void WINAPI service_ctrl(DWORD ctrlCode);static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint);static void InstallService();static void RemoveService();int service_main(int (*main_fn)(int, char **), int argc, char **argv,                  char *service_name,                  int install_flag, int run_as_service){    SERVICE_TABLE_ENTRY dispatchTable[] =    {        { service_name, service_main_fn },        { NULL, NULL }    };    globdat.name = service_name;    if(install_flag > 0)    {        InstallService();        return(0);    }    else if(install_flag < 0)    {        RemoveService();        return(0);    }    else    {        globdat.main_fn = main_fn;        globdat.stop_event = create_event(0, 0, "apache-signal");             if(run_as_service)        {            globdat.connected = 1;            if(!StartServiceCtrlDispatcher(dispatchTable))            {                return((*main_fn)(argc, argv));            }            else            {                return(globdat.exit_status);            }        }        else        {            globdat.connected = 0;            return((*main_fn)(argc, argv));        }    }}void service_cd(){    /* change to the drive with the executable */    char buf[300];    GetModuleFileName(NULL, buf, 300);    buf[2] = 0;    chdir(buf);}void __stdcall service_main_fn(DWORD argc, char **argv){    if(!(globdat.hServiceStatus = RegisterServiceCtrlHandler( globdat.name, service_ctrl)))    {        globdat.exit_status = -1;        return;    }    ReportStatusToSCMgr(        SERVICE_START_PENDING, // service state        NO_ERROR,              // exit code        3000);                 // wait hint    globdat.exit_status = (*globdat.main_fn)( argc, argv );    ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0);    return;}void service_set_status(int status){    ReportStatusToSCMgr(status, NO_ERROR, 3000);}////  FUNCTION: service_ctrl////  PURPOSE: This function is called by the SCM whenever//           ControlService() is called on this service.////  PARAMETERS://    dwCtrlCode - type of control requested////  RETURN VALUE://    none////  COMMENTS://VOID WINAPI service_ctrl(DWORD dwCtrlCode){    int state;    state = globdat.ssStatus.dwCurrentState;    switch(dwCtrlCode)    {        // Stop the service.        //        case SERVICE_CONTROL_STOP:            state = SERVICE_STOP_PENDING;	    ap_start_shutdown();            break;        // Update the service status.        //        case SERVICE_CONTROL_INTERROGATE:            break;        // invalid control code        //        default:            break;    }    ReportStatusToSCMgr(state, NO_ERROR, 0);}int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint){    static int firstTime = 1;    static int checkPoint = 1;    int rv;        if(firstTime)    {        firstTime = 0;        globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;        globdat.ssStatus.dwServiceSpecificExitCode = 0;        globdat.ssStatus.dwCheckPoint = 1;    }    if(globdat.connected)    {        if (currentState == SERVICE_START_PENDING)            globdat.ssStatus.dwControlsAccepted = 0;        else            globdat.ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;        globdat.ssStatus.dwCurrentState = currentState;        globdat.ssStatus.dwWin32ExitCode = exitCode;        if(waitHint)            globdat.ssStatus.dwWaitHint = waitHint;        if ( ( currentState == SERVICE_RUNNING ) ||             ( currentState == SERVICE_STOPPED ) )        {            globdat.ssStatus.dwWaitHint = 0;            globdat.ssStatus.dwCheckPoint = 0;        }        else            globdat.ssStatus.dwCheckPoint = ++checkPoint;        rv = SetServiceStatus(globdat.hServiceStatus, &globdat.ssStatus);    }    return(1);}void InstallService(){    SC_HANDLE   schService;    SC_HANDLE   schSCManager;    TCHAR szPath[512];    if (GetModuleFileName( NULL, szPath, 512 ) == 0)    {        exit(1);        return;    }    schSCManager = OpenSCManager(                        NULL,                   // machine (NULL == local)                        NULL,                   // database (NULL == default)                        SC_MANAGER_ALL_ACCESS   // access required                        );   if (!schSCManager) {       ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,	   "OpenSCManager failed");    }    else {        schService = CreateService(            schSCManager,               // SCManager database            globdat.name,        // name of service            globdat.name, // name to display            SERVICE_ALL_ACCESS,         // desired access            SERVICE_WIN32_OWN_PROCESS,  // service type            SERVICE_AUTO_START,       // start type            SERVICE_ERROR_NORMAL,       // error control type            szPath,                     // service's binary            NULL,                       // no load ordering group            NULL,                       // no tag identifier            NULL,       // dependencies            NULL,                       // LocalSystem account            NULL);                      // no password        if (schService) {            CloseServiceHandle(schService);	    /* Now store the server_root in the registry */	    ap_registry_set_server_root(ap_server_root);        }        else {            ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, 		"CreateService failed");        }        CloseServiceHandle(schSCManager);    }}void RemoveService(){    SC_HANDLE   schService;    SC_HANDLE   schSCManager;    schSCManager = OpenSCManager(                        NULL,                   // machine (NULL == local)                        NULL,                   // database (NULL == default)                        SC_MANAGER_ALL_ACCESS   // access required                        );    if (!schSCManager) {       ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,	   "OpenSCManager failed");    }    else {        schService = OpenService(schSCManager, globdat.name, SERVICE_ALL_ACCESS);        if (schService == NULL) {            /* Could not open the service */           ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,			"OpenService failed");        }        else {            /* try to stop the service */            if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) {                Sleep(1000);                while(QueryServiceStatus(schService, &globdat.ssStatus)) {                    if(globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING)                        Sleep(1000);                    else                        break;                }            }            // now remove the service            if (DeleteService(schService) == 0)		ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,		    "DeleteService failed");            CloseServiceHandle(schService);        }        CloseServiceHandle(schSCManager);    }}#endif /* WIN32 */

⌨️ 快捷键说明

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