📄 jk_nt_service.c
字号:
/* * Copyright 1999-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//*************************************************************************** * Description: NT System service for Jakarta/Tomcat * * Author: Gal Shachor <shachor@il.ibm.com> * * Dave Oxley <Dave@JungleMoss.com> * * Version: $Revision: 1.14 $ * ***************************************************************************/#include "jk_global.h"#include "jk_util.h"#include "jk_ajp13.h"#include "jk_connect.h"#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <process.h>#define AJP12_TAG ("ajp12")#define AJP13_TAG ("ajp13")#define BASE_REGISTRY_LOCATION ("SYSTEM\\CurrentControlSet\\Services\\")#define IMAGE_NAME ("ImagePath")#define PARAMS_LOCATION ("Parameters")#define PRP_LOCATION ("PropertyFile")// internal variablesstatic SERVICE_STATUS ssStatus; // current status of the servicestatic SERVICE_STATUS_HANDLE sshStatusHandle;static DWORD dwErr = 0;static char szErr[1024] = "";static HANDLE hServerStopEvent = NULL;static int shutdown_port;static char *shutdown_protocol = AJP12_TAG;static char *shutdown_secret = NULL;static char *shutdown_cmd=NULL;typedef enum ActionEnum{ acNoAction = 0, acInstall = 1, acRemove = 2, acStartTC = 3, acStopTC = 4} ActionEnum;struct jk_tomcat_startup_data { char *cmd_line; /* Start command line */ char *stdout_file; char *stderr_file; char *extra_path; char *tomcat_home; char *java_bin; char *shutdown_protocol; /* for cmd */ char *stop_cmd; /* For ajp13/ajp12/catalina */ int shutdown_port; char *shutdown_secret; /* Optional/not needed */ char *classpath; char *tomcat_class; char *server_file;};typedef struct jk_tomcat_startup_data jk_tomcat_startup_data_t;// internal function prototypesstatic void WINAPI service_ctrl(DWORD dwCtrlCode);static void WINAPI service_main(DWORD dwArgc, char **lpszArgv);static void install_service(char *name, char *dname, char *user, char *password, char *deps, BOOL bAutomatic, char *rel_prp_file);static void remove_service(char *name);static void start_service(char *name, char *machine);static void stop_service(char *name, char *machine);static char *GetLastErrorText(char *lpszBuf, DWORD dwSize);static void AddToMessageLog(char *lpszMsg);static BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);static void start_jk_service(char *name);static void stop_jk_service(void);static int set_registry_values(SC_HANDLE schService, char *name, char *prp_file);static int create_registry_key(const char *tag, HKEY *key);static int set_registry_config_parameter(HKEY hkey, const char *tag, char *value);static int get_registry_config_parameter(HKEY hkey, const char *tag, char *b, DWORD sz);static int start_tomcat(const char *name, HANDLE *hTomcat);static void stop_tomcat(char *name, int port, const char *protocol, char *secret, HANDLE hTomcat);static int read_startup_data(jk_map_t *init_map, jk_tomcat_startup_data_t *data, jk_pool_t *p);static int exec_cmd(const char *name, HANDLE *hTomcat, char *cmdLine);static void usage_message(const char *name){ printf("%s - Usage:\n\n", name); printf("To install the service:\n"); printf("%s -i <service name> {optional params} <config properties file>\n", name); printf(" Optional parameters\n"); printf(" -u <user name> - In the form DomainName\\UserName (.\\UserName for local)\n"); printf(" -n <service display name> - In quotes if contains non-lphanumeric chars\n"); printf(" -p <user password>\n"); printf(" -a - Set startup type to automatic\n"); printf(" -d <service dependency> - Can be entered multiple times\n\n"); printf("To remove the service:\n"); printf("%s -r <service name>\n\n", name); printf("To start the service:\n"); printf("%s -s <service name> {optional params}\n", name); printf(" Optional parameters\n"); printf(" -m <machine>\n\n"); printf("To stop the service:\n"); printf("%s -t <service name> {optional params}\n", name); printf(" Optional parameters\n"); printf(" -m <machine>\n");}void main(int argc, char **argv){ WORD wVersionRequested; WSADATA wsaData; int i; int err; int count; int iAction = acNoAction; char *pServiceDisplayName = NULL; char *pServiceName = NULL; char *pUserName = NULL; char *pPassword = NULL; char *pMachine = NULL; BOOL bAutomatic = FALSE; char strDependancy[256] = ""; memset(strDependancy, 0, 255); wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if(0 != err) { fprintf(stderr, "Error connecting to winsock"); return; } if(LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1) { fprintf(stderr, "Error winsock version is %d %d \n", LOBYTE( wsaData.wVersion ),HIBYTE( wsaData.wVersion )); WSACleanup(); return; } fprintf(stderr, "Asked (and given) winsock %d.%d \n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); __try { if(argc > 2) { count=0; for (i=1;i<argc;i++) { if ((*argv[i] == '-') || (*argv[i] == '/')) { char *cmd = argv[i]; cmd++; if(0 == stricmp("i", cmd)) { iAction = acInstall; pServiceName = argv[i+1]; } else if(0 == stricmp("r", cmd)) { iAction = acRemove; pServiceName = argv[i+1]; } else if(0 == stricmp("s", cmd)) { iAction = acStartTC; pServiceName = argv[i+1]; } else if(0 == stricmp("t", cmd)) { iAction = acStopTC; pServiceName = argv[i+1]; } else if(0 == stricmp("u", cmd)) { pUserName = argv[i+1]; } else if(0 == stricmp("p", cmd)) { pPassword = argv[i+1]; } else if(0 == stricmp("m", cmd)) { pMachine = argv[i+1]; } else if(0 == stricmp("a", cmd)) { bAutomatic = TRUE; } else if(0 == stricmp("n", cmd)) { pServiceDisplayName = argv[i+1]; } else if(0 == stricmp("d", cmd)) { memcpy(strDependancy+count, argv[i+1], strlen(argv[i+1])); count+= strlen(argv[i+1])+1; } } } switch (iAction) { case acInstall: if (pServiceDisplayName == NULL) { pServiceDisplayName = pServiceName; } install_service(pServiceName, pServiceDisplayName, pUserName, pPassword, strDependancy, bAutomatic, argv[i-1]); return; case acRemove: remove_service(pServiceName); return; case acStartTC: start_service(pServiceName, pMachine); return; case acStopTC: stop_service(pServiceName, pMachine); return; } } else if(2 == argc) { SERVICE_TABLE_ENTRY dispatchTable[] = { { argv[1], (LPSERVICE_MAIN_FUNCTION)service_main }, { NULL, NULL } }; if(!StartServiceCtrlDispatcher(dispatchTable)) { AddToMessageLog("StartServiceCtrlDispatcher failed."); } return; } usage_message(argv[0]); exit(-1); } __finally { WSACleanup(); }}void WINAPI service_main(DWORD dwArgc, char **lpszArgv){ // register our service control handler: // // sshStatusHandle = RegisterServiceCtrlHandler(lpszArgv[0], service_ctrl); if(sshStatusHandle) { ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager. // if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) { // wait hint start_jk_service(lpszArgv[0]); } } // try to report the stopped status to the service control manager. // if(sshStatusHandle) { ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0); }}void WINAPI service_ctrl(DWORD dwCtrlCode){ /* * Handle the requested control code. */ switch(dwCtrlCode) { /* * Stop the service. */ case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: ssStatus.dwCurrentState = SERVICE_STOP_PENDING; stop_jk_service(); break; /* * Update the service status. */ case SERVICE_CONTROL_INTERROGATE: break; /* * Invalid control code, nothing to do. */ default: break; } ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);}BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint){ static DWORD dwCheckPoint = 1; BOOL fResult = TRUE; if(dwCurrentState == SERVICE_START_PENDING) { ssStatus.dwControlsAccepted = 0; } else { ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; } ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwWaitHint = dwWaitHint; if((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) { ssStatus.dwCheckPoint = 0; } else { ssStatus.dwCheckPoint = dwCheckPoint++; } if(!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus))) { AddToMessageLog(TEXT("SetServiceStatus")); } return fResult;}typedef WINADVAPI BOOL (WINAPI * pfnChangeServiceConfig2_t) (SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo);void install_service(char *name, char *dname, char *user, char *password, char *deps, BOOL bAutomatic, char *rel_prp_file){ SC_HANDLE schService; SC_HANDLE schSCManager; char szExecPath[2048]; char szPropPath[2048]; char szTrueName[256]; char *dummy; char *src, *dst; dst = szTrueName; for (src = name; *src; ++src) { if (dst >= szTrueName + sizeof(szTrueName) - 1) { break; } if (!isspace(*src) && *src != '/' && *src != '\\') { *(dst++) = *src; } } *dst = '\0'; if (0 == stricmp("", deps)) deps = NULL; /* XXX strcat( deps, "Tcpip\0Afd\0" ); */ if(!GetFullPathName(rel_prp_file, sizeof(szPropPath) - 1, szPropPath, &dummy)) { printf("Unable to install %s - %s\n", name, GetLastErrorText(szErr, sizeof(szErr))); return; } if(!jk_file_exists(szPropPath)) { printf("Unable to install %s - File [%s] does not exists\n", name, szPropPath); return; } szExecPath[0] = '\"'; if(GetModuleFileName( NULL, szExecPath + 1, sizeof(szExecPath) - 2) == 0) { /* Was: if(GetModuleFileName( NULL, szExecPath, sizeof(szExecPath) - 1) == 0) { */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -