Loading CHANGES +3 −0 Original line number Original line Diff line number Diff line -*- coding: utf-8 -*- -*- coding: utf-8 -*- Changes with Apache 2.2.30 Changes with Apache 2.2.30 *) mpm_winnt: Accept utf-8 (Unicode) service names and descriptions for internationalization. [William Rowe] *) mod_log_config: Add "%{UNIT}T" format to output request duration in *) mod_log_config: Add "%{UNIT}T" format to output request duration in seconds, milliseconds or microseconds depending on UNIT ("s", "ms", "us"). seconds, milliseconds or microseconds depending on UNIT ("s", "ms", "us"). [Ben Reser, Rainer Jung] [Ben Reser, Rainer Jung] Loading STATUS +0 −6 Original line number Original line Diff line number Diff line Loading @@ -101,12 +101,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] [ start all new proposals below, under PATCHES PROPOSED. ] * mpm_winnt service.c: Accept utf-8 service names/descriptions for i18n. trunk patches: http://svn.apache.org/r1611165 http://svn.apache.org/r1611169 2.2.x patch: http://people.apache.org/~wrowe/httpd-2.2-utf8-servicename.patch +1: wrowe, gsmith * mod_log_config: Backport get_request_end_time(). * mod_log_config: Backport get_request_end_time(). This makes data consistent if a log format uses multiple %{...}T This makes data consistent if a log format uses multiple %{...}T and/or %D. The end time of a request is only taken once and the and/or %D. The end time of a request is only taken once and the Loading server/mpm/winnt/service.c +412 −88 Original line number Original line Diff line number Diff line Loading @@ -22,11 +22,18 @@ #define CORE_PRIVATE #define CORE_PRIVATE #define _WINUSER_ #define _WINUSER_ #include "apr.h" #include "apr_strings.h" #include "apr_lib.h" #if APR_HAS_UNICODE_FS #include "arch/win32/apr_arch_utf8.h" #include "arch/win32/apr_arch_misc.h" #include <wchar.h> #endif #include "httpd.h" #include "httpd.h" #include "http_log.h" #include "http_log.h" #include "mpm_winnt.h" #include "mpm_winnt.h" #include "apr_strings.h" #include "apr_lib.h" #include "ap_regkey.h" #include "ap_regkey.h" #ifdef NOUSER #ifdef NOUSER Loading @@ -39,6 +46,10 @@ static char *mpm_service_name = NULL; static char *mpm_service_name = NULL; static char *mpm_display_name = NULL; static char *mpm_display_name = NULL; #if APR_HAS_UNICODE_FS static apr_wchar_t *mpm_service_name_w; #endif static struct static struct { { HANDLE mpm_thread; /* primary thread handle of the apache server */ HANDLE mpm_thread; /* primary thread handle of the apache server */ Loading @@ -53,6 +64,33 @@ static struct static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); /* Rather than repeat this logic throughout, create an either-or wide or narrow * implementation because we don't actually pass strings to OpenSCManager. * This election is based on build time defines and runtime os version test. */ #undef OpenSCManager typedef SC_HANDLE (WINAPI *fpt_OpenSCManager)(const void *lpMachine, const void *lpDatabase, DWORD dwAccess); static fpt_OpenSCManager pfn_OpenSCManager = NULL; static APR_INLINE SC_HANDLE OpenSCManager(const void *lpMachine, const void *lpDatabase, DWORD dwAccess) { if (!pfn_OpenSCManager) { #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE pfn_OpenSCManager = (fpt_OpenSCManager)OpenSCManagerW; #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI pfn_OpenSCManager = (fpt_OpenSCManager)OpenSCManagerA; #endif } return (*(pfn_OpenSCManager))(lpMachine, lpDatabase, dwAccess); } /* The service configuration's is stored under the following trees: /* The service configuration's is stored under the following trees: * * * HKLM\System\CurrentControlSet\Services\[service name] * HKLM\System\CurrentControlSet\Services\[service name] Loading Loading @@ -408,18 +446,50 @@ static void set_service_description(void) && (ChangeServiceConfig2) && (ChangeServiceConfig2) && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) { { SC_HANDLE schService = OpenService(schSCManager, mpm_service_name, SC_HANDLE schService; #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_CHANGE_CONFIG); SERVICE_CHANGE_CONFIG); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, SERVICE_CHANGE_CONFIG); } #endif if (schService) { if (schService) { /* Cast is necessary, ChangeServiceConfig2 handles multiple /* Cast is necessary, ChangeServiceConfig2 handles multiple * object types, some volatile, some not. * object types, some volatile, some not. */ */ /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { apr_size_t slen = strlen(full_description) + 1; apr_size_t wslen = slen; apr_wchar_t *full_description_w = apr_palloc(pconf, wslen * sizeof(apr_wchar_t)); apr_status_t rv = apr_conv_utf8_to_ucs2(full_description, &slen, full_description_w, &wslen); if ((rv != APR_SUCCESS) || slen || ChangeServiceConfig2W(schService, 1 /* SERVICE_CONFIG_DESCRIPTION */, (LPVOID) &full_description_w)) full_description = NULL; } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { if (ChangeServiceConfig2(schService, if (ChangeServiceConfig2(schService, 1 /* SERVICE_CONFIG_DESCRIPTION */, 1 /* SERVICE_CONFIG_DESCRIPTION */, (LPVOID) &full_description)) { (LPVOID) &full_description)) full_description = NULL; full_description = NULL; } } #endif CloseServiceHandle(schService); CloseServiceHandle(schService); } } CloseServiceHandle(schSCManager); CloseServiceHandle(schSCManager); Loading Loading @@ -473,8 +543,82 @@ static VOID WINAPI service_nt_ctrl(DWORD dwCtrlCode) */ */ extern apr_array_header_t *mpm_new_argv; extern apr_array_header_t *mpm_new_argv; /* ###: utf-ize */ #if APR_HAS_UNICODE_FS static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) static void __stdcall service_nt_main_fn_w(DWORD argc, LPWSTR *argv) { const char *ignored; char *service_name; apr_size_t wslen = wcslen(argv[0]) + 1; apr_size_t slen = wslen * 3 - 2; service_name = malloc(slen); (void)apr_conv_ucs2_to_utf8(argv[0], &wslen, service_name, &slen); /* args and service names live in the same pool */ mpm_service_set_name(mpm_new_argv->pool, &ignored, service_name); memset(&globdat.ssStatus, 0, sizeof(globdat.ssStatus)); globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; globdat.ssStatus.dwCheckPoint = 1; if (!(globdat.hServiceStatus = RegisterServiceCtrlHandlerW(argv[0], service_nt_ctrl))) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, "Failure registering service handler"); return; } /* Report status, no errors, and buy 3 more seconds */ ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000); /* We need to append all the command arguments passed via StartService() * to our running service... which just got here via the SCM... * but we have no interest in argv[0] for the mpm_new_argv list. */ if (argc > 1) { char **cmb_data, **cmb; DWORD i; mpm_new_argv->nalloc = mpm_new_argv->nelts + argc - 1; cmb_data = malloc(mpm_new_argv->nalloc * sizeof(const char *)); /* mpm_new_argv remains first (of lower significance) */ memcpy (cmb_data, mpm_new_argv->elts, mpm_new_argv->elt_size * mpm_new_argv->nelts); /* Service args follow from StartService() invocation */ memcpy (cmb_data + mpm_new_argv->nelts, argv + 1, mpm_new_argv->elt_size * (argc - 1)); cmb = cmb_data + mpm_new_argv->nelts; for (i = 1; i < argc; ++i) { wslen = wcslen(argv[i]) + 1; slen = wslen * 3 - 2; service_name = malloc(slen); (void)apr_conv_ucs2_to_utf8(argv[i], &wslen, *(cmb++), &slen); } /* The replacement arg list is complete */ mpm_new_argv->elts = (char *)cmb_data; mpm_new_argv->nelts = mpm_new_argv->nalloc; } /* Let the main thread continue now... but hang on to the * signal_monitor event so we can take further action */ SetEvent(globdat.service_init); WaitForSingleObject(globdat.service_term, INFINITE); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS static void __stdcall service_nt_main_fn(DWORD argc, LPSTR *argv) { { const char *ignored; const char *ignored; Loading @@ -486,8 +630,7 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; globdat.ssStatus.dwCheckPoint = 1; globdat.ssStatus.dwCheckPoint = 1; /* ###: utf-ize */ if (!(globdat.hServiceStatus = RegisterServiceCtrlHandlerA(argv[0], service_nt_ctrl))) if (!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], service_nt_ctrl))) { { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, "Failure registering service handler"); NULL, "Failure registering service handler"); Loading @@ -499,7 +642,7 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) /* We need to append all the command arguments passed via StartService() /* We need to append all the command arguments passed via StartService() * to our running service... which just got here via the SCM... * to our running service... which just got here via the SCM... * but we hvae no interest in argv[0] for the mpm_new_argv list. * but we have no interest in argv[0] for the mpm_new_argv list. */ */ if (argc > 1) if (argc > 1) { { Loading Loading @@ -528,27 +671,44 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) WaitForSingleObject(globdat.service_term, INFINITE); WaitForSingleObject(globdat.service_term, INFINITE); } } #endif static DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) static DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) { { apr_status_t rv = APR_SUCCESS; #if APR_HAS_UNICODE_FS SERVICE_TABLE_ENTRYW dispatchTable_w[] = SERVICE_TABLE_ENTRY dispatchTable[] = { { L"", service_nt_main_fn_w }, { NULL, NULL } }; #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS SERVICE_TABLE_ENTRYA dispatchTable[] = { { { "", service_nt_main_fn }, { "", service_nt_main_fn }, { NULL, NULL } { NULL, NULL } }; }; #endif apr_status_t rv; /* ###: utf-ize */ #if APR_HAS_UNICODE_FS if (!StartServiceCtrlDispatcher(dispatchTable)) IF_WIN_OS_IS_UNICODE { rv = StartServiceCtrlDispatcherW(dispatchTable_w); #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI rv = StartServiceCtrlDispatcherA(dispatchTable); #endif if (rv) { apr_status_t rv = APR_SUCCESS; } else { /* This is a genuine failure of the SCM. */ /* This is a genuine failure of the SCM. */ rv = apr_get_os_error(); rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "Error starting service control dispatcher"); "Error starting service control dispatcher"); } } return (rv); return (rv); } } Loading @@ -566,6 +726,21 @@ apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, */ */ mpm_service_name = apr_palloc(p, strlen(set_name) + 1); mpm_service_name = apr_palloc(p, strlen(set_name) + 1); apr_collapse_spaces((char*) mpm_service_name, set_name); apr_collapse_spaces((char*) mpm_service_name, set_name); #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { apr_size_t slen = strlen(mpm_service_name) + 1; apr_size_t wslen = slen; mpm_service_name_w = apr_palloc(p, wslen * sizeof(apr_wchar_t)); rv = apr_conv_utf8_to_ucs2(mpm_service_name, &slen, mpm_service_name_w, &wslen); if (rv != APR_SUCCESS) return rv; else if (slen) return APR_ENAMETOOLONG; } #endif /* APR_HAS_UNICODE_FS */ apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf); if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) { Loading @@ -577,6 +752,7 @@ apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, mpm_display_name = apr_pstrdup(p, set_name); mpm_display_name = apr_pstrdup(p, set_name); } } *display_name = mpm_display_name; *display_name = mpm_display_name; return rv; return rv; } } Loading Loading @@ -756,28 +932,56 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, const char * const * argv, int reconfig) const char * const * argv, int reconfig) { { char key_name[MAX_PATH]; char key_name[MAX_PATH]; char exe_path[MAX_PATH]; char *launch_cmd; ap_regkey_t *key; ap_regkey_t *key; char *launch_cmd; apr_status_t rv; apr_status_t rv; fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" : "Installing the %s service\n", mpm_display_name); : "Installing the %s service\n", mpm_display_name); /* ###: utf-ize */ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) { { apr_status_t rv = apr_get_os_error(); SC_HANDLE schService; SC_HANDLE schSCManager; DWORD rc; #if APR_HAS_UNICODE_FS apr_wchar_t *display_name_w; apr_wchar_t *launch_cmd_w; IF_WIN_OS_IS_UNICODE { apr_size_t slen = strlen(mpm_display_name) + 1; apr_size_t wslen = slen; display_name_w = apr_palloc(ptemp, wslen * sizeof(apr_wchar_t)); rv = apr_conv_utf8_to_ucs2(mpm_display_name, &slen, display_name_w, &wslen); if (rv != APR_SUCCESS) return rv; else if (slen) return APR_ENAMETOOLONG; launch_cmd_w = apr_palloc(ptemp, (MAX_PATH + 17) * sizeof(apr_wchar_t)); launch_cmd_w[0] = L'"'; rc = GetModuleFileNameW(NULL, launch_cmd_w + 1, MAX_PATH); wcscpy(launch_cmd_w + rc + 1, L"\" -k runservice"); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { launch_cmd = apr_palloc(ptemp, MAX_PATH + 17); launch_cmd[0] = '"'; rc = GetModuleFileName(NULL, launch_cmd + 1, MAX_PATH); strcpy(launch_cmd + rc + 1, "\" -k runservice"); } #endif if (rc == 0) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "GetModuleFileName failed"); "GetModuleFileName failed"); return rv; return rv; } } if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { SC_HANDLE schService; SC_HANDLE schSCManager; schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ SC_MANAGER_CREATE_SERVICE); SC_MANAGER_CREATE_SERVICE); if (!schSCManager) { if (!schSCManager) { Loading @@ -787,25 +991,52 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, return (rv); return (rv); } } launch_cmd = apr_psprintf(ptemp, "\"%s\" -k runservice", exe_path); if (reconfig) { if (reconfig) { /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_CHANGE_CONFIG); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, schService = OpenService(schSCManager, mpm_service_name, SERVICE_CHANGE_CONFIG); SERVICE_CHANGE_CONFIG); } #endif if (!schService) { if (!schService) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, apr_get_os_error(), NULL, apr_get_os_error(), NULL, "OpenService failed"); "OpenService failed"); } } /* ###: utf-ize */ else { else if (!ChangeServiceConfig(schService, #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { rc = ChangeServiceConfigW(schService, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, launch_cmd_w, NULL, NULL, L"Tcpip\0Afd\0", NULL, NULL, display_name_w); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { rc = ChangeServiceConfig(schService, SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, SERVICE_ERROR_NORMAL, launch_cmd, NULL, NULL, launch_cmd, NULL, NULL, "Tcpip\0Afd\0", NULL, NULL, "Tcpip\0Afd\0", NULL, NULL, mpm_display_name)) { mpm_display_name); } #endif if (!rc) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, apr_get_os_error(), NULL, apr_get_os_error(), NULL, "ChangeServiceConfig failed"); "ChangeServiceConfig failed"); Loading @@ -814,6 +1045,7 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, schService = NULL; schService = NULL; } } } } } else { else { /* RPCSS is the Remote Procedure Call (RPC) Locator required /* RPCSS is the Remote Procedure Call (RPC) Locator required * for DCOM communication pipes. I am far from convinced we * for DCOM communication pipes. I am far from convinced we Loading @@ -821,7 +1053,28 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, * be warned that future apache modules or ISAPI dll's may * be warned that future apache modules or ISAPI dll's may * depend on it. * depend on it. */ */ /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = CreateServiceW(schSCManager, // SCManager database mpm_service_name_w, // name of service display_name_w, // name to display SERVICE_ALL_ACCESS, // access required SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type launch_cmd_w, // service's binary NULL, // no load svc group NULL, // no tag identifier L"Tcpip\0Afd\0", // dependencies NULL, // use SYSTEM account NULL); // no password } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = CreateService(schSCManager, // SCManager database schService = CreateService(schSCManager, // SCManager database mpm_service_name, // name of service mpm_service_name, // name of service mpm_display_name, // name to display mpm_display_name, // name to display Loading @@ -835,7 +1088,8 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, "Tcpip\0Afd\0", // dependencies "Tcpip\0Afd\0", // dependencies NULL, // use SYSTEM account NULL, // use SYSTEM account NULL); // no password NULL); // no password } #endif if (!schService) if (!schService) { { rv = apr_get_os_error(); rv = apr_get_os_error(); Loading @@ -851,6 +1105,16 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, } } else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ { { char exe_path[MAX_PATH]; if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) { apr_status_t rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "GetModuleFileName failed"); return rv; } /* Store the launch command in the registry */ /* Store the launch command in the registry */ launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", exe_path, mpm_service_name); exe_path, mpm_service_name); Loading Loading @@ -939,9 +1203,18 @@ apr_status_t mpm_service_uninstall(void) return (rv); return (rv); } } /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, DELETE); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, DELETE); schService = OpenService(schSCManager, mpm_service_name, DELETE); } #endif if (!schService) { if (!schService) { rv = apr_get_os_error(); rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, Loading Loading @@ -1040,7 +1313,6 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { { CHAR **start_argv; SC_HANDLE schService; SC_HANDLE schService; SC_HANDLE schSCManager; SC_HANDLE schSCManager; Loading @@ -1053,9 +1325,20 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, return (rv); return (rv); } } /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_START | SERVICE_QUERY_STATUS); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, schService = OpenService(schSCManager, mpm_service_name, SERVICE_START | SERVICE_QUERY_STATUS); SERVICE_START | SERVICE_QUERY_STATUS); } #endif if (!schService) { if (!schService) { rv = apr_get_os_error(); rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, Loading @@ -1073,18 +1356,47 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, return 0; return 0; } } start_argv = malloc((argc + 1) * sizeof(const char **)); rv = APR_EINIT; memcpy(start_argv, argv, argc * sizeof(const char **)); #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { LPWSTR *start_argv_w = malloc((argc + 1) * sizeof(LPCWSTR)); int i; for (i = 0; i < argc; ++i) { apr_size_t slen = strlen(argv[i]) + 1; apr_size_t wslen = slen; start_argv_w[i] = malloc(wslen * sizeof(WCHAR)); rv = apr_conv_utf8_to_ucs2(argv[i], &slen, start_argv_w[i], &wslen); if (rv != APR_SUCCESS) return rv; else if (slen) return APR_ENAMETOOLONG; } start_argv_w[argc] = NULL; if (StartServiceW(schService, argc, start_argv_w) && signal_service_transition(schService, 0, /* test only */ SERVICE_START_PENDING, SERVICE_RUNNING)) rv = APR_SUCCESS; } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { char **start_argv = malloc((argc + 1) * sizeof(const char *)); memcpy(start_argv, argv, argc * sizeof(const char *)); start_argv[argc] = NULL; start_argv[argc] = NULL; rv = APR_EINIT; /* ###: utf-ize */ if (StartService(schService, argc, start_argv) if (StartService(schService, argc, start_argv) && signal_service_transition(schService, 0, /* test only */ && signal_service_transition(schService, 0, /* test only */ SERVICE_START_PENDING, SERVICE_START_PENDING, SERVICE_RUNNING)) SERVICE_RUNNING)) rv = APR_SUCCESS; rv = APR_SUCCESS; } #endif if (rv != APR_SUCCESS) if (rv != APR_SUCCESS) rv = apr_get_os_error(); rv = apr_get_os_error(); Loading Loading @@ -1193,12 +1505,24 @@ void mpm_signal_service(apr_pool_t *ptemp, int signal) return; return; } } /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL | SERVICE_START | SERVICE_STOP); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, schService = OpenService(schSCManager, mpm_service_name, SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL | SERVICE_USER_DEFINED_CONTROL | SERVICE_START | SERVICE_STOP); SERVICE_START | SERVICE_STOP); } #endif if (schService == NULL) { if (schService == NULL) { /* Could not open the service */ /* Could not open the service */ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, Loading Loading
CHANGES +3 −0 Original line number Original line Diff line number Diff line -*- coding: utf-8 -*- -*- coding: utf-8 -*- Changes with Apache 2.2.30 Changes with Apache 2.2.30 *) mpm_winnt: Accept utf-8 (Unicode) service names and descriptions for internationalization. [William Rowe] *) mod_log_config: Add "%{UNIT}T" format to output request duration in *) mod_log_config: Add "%{UNIT}T" format to output request duration in seconds, milliseconds or microseconds depending on UNIT ("s", "ms", "us"). seconds, milliseconds or microseconds depending on UNIT ("s", "ms", "us"). [Ben Reser, Rainer Jung] [Ben Reser, Rainer Jung] Loading
STATUS +0 −6 Original line number Original line Diff line number Diff line Loading @@ -101,12 +101,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] [ start all new proposals below, under PATCHES PROPOSED. ] * mpm_winnt service.c: Accept utf-8 service names/descriptions for i18n. trunk patches: http://svn.apache.org/r1611165 http://svn.apache.org/r1611169 2.2.x patch: http://people.apache.org/~wrowe/httpd-2.2-utf8-servicename.patch +1: wrowe, gsmith * mod_log_config: Backport get_request_end_time(). * mod_log_config: Backport get_request_end_time(). This makes data consistent if a log format uses multiple %{...}T This makes data consistent if a log format uses multiple %{...}T and/or %D. The end time of a request is only taken once and the and/or %D. The end time of a request is only taken once and the Loading
server/mpm/winnt/service.c +412 −88 Original line number Original line Diff line number Diff line Loading @@ -22,11 +22,18 @@ #define CORE_PRIVATE #define CORE_PRIVATE #define _WINUSER_ #define _WINUSER_ #include "apr.h" #include "apr_strings.h" #include "apr_lib.h" #if APR_HAS_UNICODE_FS #include "arch/win32/apr_arch_utf8.h" #include "arch/win32/apr_arch_misc.h" #include <wchar.h> #endif #include "httpd.h" #include "httpd.h" #include "http_log.h" #include "http_log.h" #include "mpm_winnt.h" #include "mpm_winnt.h" #include "apr_strings.h" #include "apr_lib.h" #include "ap_regkey.h" #include "ap_regkey.h" #ifdef NOUSER #ifdef NOUSER Loading @@ -39,6 +46,10 @@ static char *mpm_service_name = NULL; static char *mpm_service_name = NULL; static char *mpm_display_name = NULL; static char *mpm_display_name = NULL; #if APR_HAS_UNICODE_FS static apr_wchar_t *mpm_service_name_w; #endif static struct static struct { { HANDLE mpm_thread; /* primary thread handle of the apache server */ HANDLE mpm_thread; /* primary thread handle of the apache server */ Loading @@ -53,6 +64,33 @@ static struct static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); /* Rather than repeat this logic throughout, create an either-or wide or narrow * implementation because we don't actually pass strings to OpenSCManager. * This election is based on build time defines and runtime os version test. */ #undef OpenSCManager typedef SC_HANDLE (WINAPI *fpt_OpenSCManager)(const void *lpMachine, const void *lpDatabase, DWORD dwAccess); static fpt_OpenSCManager pfn_OpenSCManager = NULL; static APR_INLINE SC_HANDLE OpenSCManager(const void *lpMachine, const void *lpDatabase, DWORD dwAccess) { if (!pfn_OpenSCManager) { #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE pfn_OpenSCManager = (fpt_OpenSCManager)OpenSCManagerW; #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI pfn_OpenSCManager = (fpt_OpenSCManager)OpenSCManagerA; #endif } return (*(pfn_OpenSCManager))(lpMachine, lpDatabase, dwAccess); } /* The service configuration's is stored under the following trees: /* The service configuration's is stored under the following trees: * * * HKLM\System\CurrentControlSet\Services\[service name] * HKLM\System\CurrentControlSet\Services\[service name] Loading Loading @@ -408,18 +446,50 @@ static void set_service_description(void) && (ChangeServiceConfig2) && (ChangeServiceConfig2) && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) && (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) { { SC_HANDLE schService = OpenService(schSCManager, mpm_service_name, SC_HANDLE schService; #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_CHANGE_CONFIG); SERVICE_CHANGE_CONFIG); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, SERVICE_CHANGE_CONFIG); } #endif if (schService) { if (schService) { /* Cast is necessary, ChangeServiceConfig2 handles multiple /* Cast is necessary, ChangeServiceConfig2 handles multiple * object types, some volatile, some not. * object types, some volatile, some not. */ */ /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { apr_size_t slen = strlen(full_description) + 1; apr_size_t wslen = slen; apr_wchar_t *full_description_w = apr_palloc(pconf, wslen * sizeof(apr_wchar_t)); apr_status_t rv = apr_conv_utf8_to_ucs2(full_description, &slen, full_description_w, &wslen); if ((rv != APR_SUCCESS) || slen || ChangeServiceConfig2W(schService, 1 /* SERVICE_CONFIG_DESCRIPTION */, (LPVOID) &full_description_w)) full_description = NULL; } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { if (ChangeServiceConfig2(schService, if (ChangeServiceConfig2(schService, 1 /* SERVICE_CONFIG_DESCRIPTION */, 1 /* SERVICE_CONFIG_DESCRIPTION */, (LPVOID) &full_description)) { (LPVOID) &full_description)) full_description = NULL; full_description = NULL; } } #endif CloseServiceHandle(schService); CloseServiceHandle(schService); } } CloseServiceHandle(schSCManager); CloseServiceHandle(schSCManager); Loading Loading @@ -473,8 +543,82 @@ static VOID WINAPI service_nt_ctrl(DWORD dwCtrlCode) */ */ extern apr_array_header_t *mpm_new_argv; extern apr_array_header_t *mpm_new_argv; /* ###: utf-ize */ #if APR_HAS_UNICODE_FS static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) static void __stdcall service_nt_main_fn_w(DWORD argc, LPWSTR *argv) { const char *ignored; char *service_name; apr_size_t wslen = wcslen(argv[0]) + 1; apr_size_t slen = wslen * 3 - 2; service_name = malloc(slen); (void)apr_conv_ucs2_to_utf8(argv[0], &wslen, service_name, &slen); /* args and service names live in the same pool */ mpm_service_set_name(mpm_new_argv->pool, &ignored, service_name); memset(&globdat.ssStatus, 0, sizeof(globdat.ssStatus)); globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; globdat.ssStatus.dwCheckPoint = 1; if (!(globdat.hServiceStatus = RegisterServiceCtrlHandlerW(argv[0], service_nt_ctrl))) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, "Failure registering service handler"); return; } /* Report status, no errors, and buy 3 more seconds */ ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 30000); /* We need to append all the command arguments passed via StartService() * to our running service... which just got here via the SCM... * but we have no interest in argv[0] for the mpm_new_argv list. */ if (argc > 1) { char **cmb_data, **cmb; DWORD i; mpm_new_argv->nalloc = mpm_new_argv->nelts + argc - 1; cmb_data = malloc(mpm_new_argv->nalloc * sizeof(const char *)); /* mpm_new_argv remains first (of lower significance) */ memcpy (cmb_data, mpm_new_argv->elts, mpm_new_argv->elt_size * mpm_new_argv->nelts); /* Service args follow from StartService() invocation */ memcpy (cmb_data + mpm_new_argv->nelts, argv + 1, mpm_new_argv->elt_size * (argc - 1)); cmb = cmb_data + mpm_new_argv->nelts; for (i = 1; i < argc; ++i) { wslen = wcslen(argv[i]) + 1; slen = wslen * 3 - 2; service_name = malloc(slen); (void)apr_conv_ucs2_to_utf8(argv[i], &wslen, *(cmb++), &slen); } /* The replacement arg list is complete */ mpm_new_argv->elts = (char *)cmb_data; mpm_new_argv->nelts = mpm_new_argv->nalloc; } /* Let the main thread continue now... but hang on to the * signal_monitor event so we can take further action */ SetEvent(globdat.service_init); WaitForSingleObject(globdat.service_term, INFINITE); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS static void __stdcall service_nt_main_fn(DWORD argc, LPSTR *argv) { { const char *ignored; const char *ignored; Loading @@ -486,8 +630,7 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; globdat.ssStatus.dwCurrentState = SERVICE_START_PENDING; globdat.ssStatus.dwCheckPoint = 1; globdat.ssStatus.dwCheckPoint = 1; /* ###: utf-ize */ if (!(globdat.hServiceStatus = RegisterServiceCtrlHandlerA(argv[0], service_nt_ctrl))) if (!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], service_nt_ctrl))) { { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, "Failure registering service handler"); NULL, "Failure registering service handler"); Loading @@ -499,7 +642,7 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) /* We need to append all the command arguments passed via StartService() /* We need to append all the command arguments passed via StartService() * to our running service... which just got here via the SCM... * to our running service... which just got here via the SCM... * but we hvae no interest in argv[0] for the mpm_new_argv list. * but we have no interest in argv[0] for the mpm_new_argv list. */ */ if (argc > 1) if (argc > 1) { { Loading Loading @@ -528,27 +671,44 @@ static void __stdcall service_nt_main_fn(DWORD argc, LPTSTR *argv) WaitForSingleObject(globdat.service_term, INFINITE); WaitForSingleObject(globdat.service_term, INFINITE); } } #endif static DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) static DWORD WINAPI service_nt_dispatch_thread(LPVOID nada) { { apr_status_t rv = APR_SUCCESS; #if APR_HAS_UNICODE_FS SERVICE_TABLE_ENTRYW dispatchTable_w[] = SERVICE_TABLE_ENTRY dispatchTable[] = { { L"", service_nt_main_fn_w }, { NULL, NULL } }; #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS SERVICE_TABLE_ENTRYA dispatchTable[] = { { { "", service_nt_main_fn }, { "", service_nt_main_fn }, { NULL, NULL } { NULL, NULL } }; }; #endif apr_status_t rv; /* ###: utf-ize */ #if APR_HAS_UNICODE_FS if (!StartServiceCtrlDispatcher(dispatchTable)) IF_WIN_OS_IS_UNICODE { rv = StartServiceCtrlDispatcherW(dispatchTable_w); #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI rv = StartServiceCtrlDispatcherA(dispatchTable); #endif if (rv) { apr_status_t rv = APR_SUCCESS; } else { /* This is a genuine failure of the SCM. */ /* This is a genuine failure of the SCM. */ rv = apr_get_os_error(); rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "Error starting service control dispatcher"); "Error starting service control dispatcher"); } } return (rv); return (rv); } } Loading @@ -566,6 +726,21 @@ apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, */ */ mpm_service_name = apr_palloc(p, strlen(set_name) + 1); mpm_service_name = apr_palloc(p, strlen(set_name) + 1); apr_collapse_spaces((char*) mpm_service_name, set_name); apr_collapse_spaces((char*) mpm_service_name, set_name); #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { apr_size_t slen = strlen(mpm_service_name) + 1; apr_size_t wslen = slen; mpm_service_name_w = apr_palloc(p, wslen * sizeof(apr_wchar_t)); rv = apr_conv_utf8_to_ucs2(mpm_service_name, &slen, mpm_service_name_w, &wslen); if (rv != APR_SUCCESS) return rv; else if (slen) return APR_ENAMETOOLONG; } #endif /* APR_HAS_UNICODE_FS */ apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ, pconf); if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) { Loading @@ -577,6 +752,7 @@ apr_status_t mpm_service_set_name(apr_pool_t *p, const char **display_name, mpm_display_name = apr_pstrdup(p, set_name); mpm_display_name = apr_pstrdup(p, set_name); } } *display_name = mpm_display_name; *display_name = mpm_display_name; return rv; return rv; } } Loading Loading @@ -756,28 +932,56 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, const char * const * argv, int reconfig) const char * const * argv, int reconfig) { { char key_name[MAX_PATH]; char key_name[MAX_PATH]; char exe_path[MAX_PATH]; char *launch_cmd; ap_regkey_t *key; ap_regkey_t *key; char *launch_cmd; apr_status_t rv; apr_status_t rv; fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" : "Installing the %s service\n", mpm_display_name); : "Installing the %s service\n", mpm_display_name); /* ###: utf-ize */ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) { { apr_status_t rv = apr_get_os_error(); SC_HANDLE schService; SC_HANDLE schSCManager; DWORD rc; #if APR_HAS_UNICODE_FS apr_wchar_t *display_name_w; apr_wchar_t *launch_cmd_w; IF_WIN_OS_IS_UNICODE { apr_size_t slen = strlen(mpm_display_name) + 1; apr_size_t wslen = slen; display_name_w = apr_palloc(ptemp, wslen * sizeof(apr_wchar_t)); rv = apr_conv_utf8_to_ucs2(mpm_display_name, &slen, display_name_w, &wslen); if (rv != APR_SUCCESS) return rv; else if (slen) return APR_ENAMETOOLONG; launch_cmd_w = apr_palloc(ptemp, (MAX_PATH + 17) * sizeof(apr_wchar_t)); launch_cmd_w[0] = L'"'; rc = GetModuleFileNameW(NULL, launch_cmd_w + 1, MAX_PATH); wcscpy(launch_cmd_w + rc + 1, L"\" -k runservice"); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { launch_cmd = apr_palloc(ptemp, MAX_PATH + 17); launch_cmd[0] = '"'; rc = GetModuleFileName(NULL, launch_cmd + 1, MAX_PATH); strcpy(launch_cmd + rc + 1, "\" -k runservice"); } #endif if (rc == 0) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "GetModuleFileName failed"); "GetModuleFileName failed"); return rv; return rv; } } if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { SC_HANDLE schService; SC_HANDLE schSCManager; schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ SC_MANAGER_CREATE_SERVICE); SC_MANAGER_CREATE_SERVICE); if (!schSCManager) { if (!schSCManager) { Loading @@ -787,25 +991,52 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, return (rv); return (rv); } } launch_cmd = apr_psprintf(ptemp, "\"%s\" -k runservice", exe_path); if (reconfig) { if (reconfig) { /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_CHANGE_CONFIG); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, schService = OpenService(schSCManager, mpm_service_name, SERVICE_CHANGE_CONFIG); SERVICE_CHANGE_CONFIG); } #endif if (!schService) { if (!schService) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, apr_get_os_error(), NULL, apr_get_os_error(), NULL, "OpenService failed"); "OpenService failed"); } } /* ###: utf-ize */ else { else if (!ChangeServiceConfig(schService, #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { rc = ChangeServiceConfigW(schService, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, launch_cmd_w, NULL, NULL, L"Tcpip\0Afd\0", NULL, NULL, display_name_w); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { rc = ChangeServiceConfig(schService, SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, SERVICE_ERROR_NORMAL, launch_cmd, NULL, NULL, launch_cmd, NULL, NULL, "Tcpip\0Afd\0", NULL, NULL, "Tcpip\0Afd\0", NULL, NULL, mpm_display_name)) { mpm_display_name); } #endif if (!rc) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, apr_get_os_error(), NULL, apr_get_os_error(), NULL, "ChangeServiceConfig failed"); "ChangeServiceConfig failed"); Loading @@ -814,6 +1045,7 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, schService = NULL; schService = NULL; } } } } } else { else { /* RPCSS is the Remote Procedure Call (RPC) Locator required /* RPCSS is the Remote Procedure Call (RPC) Locator required * for DCOM communication pipes. I am far from convinced we * for DCOM communication pipes. I am far from convinced we Loading @@ -821,7 +1053,28 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, * be warned that future apache modules or ISAPI dll's may * be warned that future apache modules or ISAPI dll's may * depend on it. * depend on it. */ */ /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = CreateServiceW(schSCManager, // SCManager database mpm_service_name_w, // name of service display_name_w, // name to display SERVICE_ALL_ACCESS, // access required SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type launch_cmd_w, // service's binary NULL, // no load svc group NULL, // no tag identifier L"Tcpip\0Afd\0", // dependencies NULL, // use SYSTEM account NULL); // no password } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = CreateService(schSCManager, // SCManager database schService = CreateService(schSCManager, // SCManager database mpm_service_name, // name of service mpm_service_name, // name of service mpm_display_name, // name to display mpm_display_name, // name to display Loading @@ -835,7 +1088,8 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, "Tcpip\0Afd\0", // dependencies "Tcpip\0Afd\0", // dependencies NULL, // use SYSTEM account NULL, // use SYSTEM account NULL); // no password NULL); // no password } #endif if (!schService) if (!schService) { { rv = apr_get_os_error(); rv = apr_get_os_error(); Loading @@ -851,6 +1105,16 @@ apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, } } else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ { { char exe_path[MAX_PATH]; if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) { apr_status_t rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "GetModuleFileName failed"); return rv; } /* Store the launch command in the registry */ /* Store the launch command in the registry */ launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", exe_path, mpm_service_name); exe_path, mpm_service_name); Loading Loading @@ -939,9 +1203,18 @@ apr_status_t mpm_service_uninstall(void) return (rv); return (rv); } } /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, DELETE); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, DELETE); schService = OpenService(schSCManager, mpm_service_name, DELETE); } #endif if (!schService) { if (!schService) { rv = apr_get_os_error(); rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, Loading Loading @@ -1040,7 +1313,6 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { { CHAR **start_argv; SC_HANDLE schService; SC_HANDLE schService; SC_HANDLE schSCManager; SC_HANDLE schSCManager; Loading @@ -1053,9 +1325,20 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, return (rv); return (rv); } } /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_START | SERVICE_QUERY_STATUS); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, schService = OpenService(schSCManager, mpm_service_name, SERVICE_START | SERVICE_QUERY_STATUS); SERVICE_START | SERVICE_QUERY_STATUS); } #endif if (!schService) { if (!schService) { rv = apr_get_os_error(); rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, Loading @@ -1073,18 +1356,47 @@ apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc, return 0; return 0; } } start_argv = malloc((argc + 1) * sizeof(const char **)); rv = APR_EINIT; memcpy(start_argv, argv, argc * sizeof(const char **)); #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { LPWSTR *start_argv_w = malloc((argc + 1) * sizeof(LPCWSTR)); int i; for (i = 0; i < argc; ++i) { apr_size_t slen = strlen(argv[i]) + 1; apr_size_t wslen = slen; start_argv_w[i] = malloc(wslen * sizeof(WCHAR)); rv = apr_conv_utf8_to_ucs2(argv[i], &slen, start_argv_w[i], &wslen); if (rv != APR_SUCCESS) return rv; else if (slen) return APR_ENAMETOOLONG; } start_argv_w[argc] = NULL; if (StartServiceW(schService, argc, start_argv_w) && signal_service_transition(schService, 0, /* test only */ SERVICE_START_PENDING, SERVICE_RUNNING)) rv = APR_SUCCESS; } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { char **start_argv = malloc((argc + 1) * sizeof(const char *)); memcpy(start_argv, argv, argc * sizeof(const char *)); start_argv[argc] = NULL; start_argv[argc] = NULL; rv = APR_EINIT; /* ###: utf-ize */ if (StartService(schService, argc, start_argv) if (StartService(schService, argc, start_argv) && signal_service_transition(schService, 0, /* test only */ && signal_service_transition(schService, 0, /* test only */ SERVICE_START_PENDING, SERVICE_START_PENDING, SERVICE_RUNNING)) SERVICE_RUNNING)) rv = APR_SUCCESS; rv = APR_SUCCESS; } #endif if (rv != APR_SUCCESS) if (rv != APR_SUCCESS) rv = apr_get_os_error(); rv = apr_get_os_error(); Loading Loading @@ -1193,12 +1505,24 @@ void mpm_signal_service(apr_pool_t *ptemp, int signal) return; return; } } /* ###: utf-ize */ #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { schService = OpenServiceW(schSCManager, mpm_service_name_w, SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL | SERVICE_START | SERVICE_STOP); } #endif /* APR_HAS_UNICODE_FS */ #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { schService = OpenService(schSCManager, mpm_service_name, schService = OpenService(schSCManager, mpm_service_name, SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | SERVICE_INTERROGATE | SERVICE_QUERY_STATUS | SERVICE_USER_DEFINED_CONTROL | SERVICE_USER_DEFINED_CONTROL | SERVICE_START | SERVICE_STOP); SERVICE_START | SERVICE_STOP); } #endif if (schService == NULL) { if (schService == NULL) { /* Could not open the service */ /* Could not open the service */ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL, Loading