You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Keijser, Jan Just" <KE...@logica.com> on 1999/10/06 23:19:13 UTC
[PATCH] Several patches for running Apache 1.3.9 on Win95
This patch is intended to fix/address PR2472, PR4125, PR1643 (suspended) and
PR2208 (suspended).
This patch does several things:
1. Adds support to run Apache as a service on Win95. This service will run
without any users logging on to the system and will continue to run until
the system is shutdown (PR2208);
2. Making sure that Apache is shut down when the system is shutdown. This is
done by spawning an extra thread, which monitors the system shutdown
messages; if this message is seen, it will shutdown Apache using
'send_signal( "shutdown" )' (PR1643, PR2472)
3. Installing/Uninstalling Apache on Win95 is done using the same syntax as
on NT (i.e. apache -i/-u)
4. Pressing Ctrl-C in the Apache console window will cause Apache to clean
up nicely and then shut down. This is done using a ConsoleCtrlHandler;
5. Apache will try to close the console window when possible; in most cases
this will result in the console window disappearing after the successful
launch of Apache. The console window will NOT be closed if the user starts a
DOS box and then starts Apache from within that DOS box. This is required to
make Apache shut down cleanly when run on Windows 95, otherwise Apache seems
to prevent a system shutdown (PR4125)
Extra:
- The command "apache -s" will start Apache as a service on Win95; this is
necessary when installing Apache as a service, since there is no easy method
on Win95 for determining whether an app is run as a service or by a user.
All diffs are based on the Apache 1.3.9 Win32 source code.
*** main/http_main-old.c Tue Aug 11 08:54:48 1999
--- main/http_main.c Wed Oct 06 15:46:12 1999
***************
*** 1062,1067 ****
--- 1062,1068 ----
fprintf(stderr, " -k start : tell Apache to start\n");
fprintf(stderr, " -i : install an Apache service\n");
fprintf(stderr, " -u : uninstall an Apache service\n");
+ fprintf(stderr, " -s : run Apache as a service (Win9x
only)\n");
#endif
exit(1);
}
***************
*** 1262,1267 ****
--- 1263,1296 ----
else
return (0);
}
+
+ /* Control handler for processing Ctrl-C/Ctrl-Break and
+ * on Windows NT also user logoff and system shutdown
+ */
+
+ /* Is defined later in this file */
+ int send_signal(pool *p, char *signal);
+
+ BOOL WINAPI ap_control_handler( DWORD ctrl_type )
+ {
+ switch ( ctrl_type )
+ {
+ case CTRL_C_EVENT:
+ printf( "Caught Ctrl-Break, shutting down...\n" );
+ /* The following only work on NT, despite the manuals... */
+ case CTRL_CLOSE_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ /* for all known signals, shut down the server */
+ send_signal( pconf, "shutdown" );
+ /* Tell the system we have dealt with the signal */
+ return TRUE;
+ break;
+ }
+
+ /* We should never get here, but this is harmless */
+ return FALSE;
+ }
#endif /* WIN32 */
***************
*** 5944,5949 ****
--- 5973,6064 ----
}
}
+
+ /* This is the WndProc procedure for our invisible window.
+ * When the user shuts down the system, this window is sent
+ * a signal WM_QUERYENDSESSION with lParam == 0 to indicate
+ * a system shutdown. We clean up by shutting down Apache and
+ * indicate to the system that the message was received and
+ * understood (return TRUE).
+ * If a user logs off, the window is sent WM_QUERYENDSESSION
+ * as well, but with lParam != 0. We ignore this case.
+ */
+ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
+ {
+ switch (message)
+ {
+ case WM_QUERYENDSESSION:
+ if ( lParam == 0 )
+ {
+ /* Tell Apache to shut down gracefully */
+ send_signal( pconf, "shutdown" );
+ }
+ return TRUE;
+ break;
+ }
+
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+
+
+ DWORD WINAPI WatchWindow( void *junk )
+ {
+ /* When running on Windows 9x, the ConsoleCtrlHandler is _NOT_
+ * called when the system is shutdown or the user logs off, nor
+ * are there any other signals that console applications get.
+ * So we create an invisible window and set up a WndProc for
+ * this window. Funny enough, this window DOES receive a signal
+ * when the user is logging off or the system is shutting down.
+ * We need to deal with both cases in our own WndProc routine.
+ */
+ WNDCLASS wc;
+ HWND hwndMain;
+
+ wc.style = CS_GLOBALCLASS;
+ wc.lpfnWndProc = (WNDPROC) WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = NULL;
+ wc.hIcon = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "SleepyMonkey";
+
+ if (RegisterClass(&wc))
+ {
+ /* Create an invisible window */
+ hwndMain = CreateWindow("SleepyMonkey", "Apache",
+ WS_OVERLAPPEDWINDOW & ~WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL,
NULL);
+
+ if ( hwndMain )
+ {
+ MSG msg;
+
+ while (GetMessage(&msg, hwndMain, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ }
+ else
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR,
NULL,
+ "Could not create
WatchWindow");
+ }
+ }
+ else
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
+ "Could not register window class for
WatchWindow");
+ }
+
+ return 0;
+ }
+
+
int master_main(int argc, char **argv)
{
/* returns NULL if invalid (Win95?) */
***************
*** 6002,6012 ****
start_mutex = ap_create_mutex(signal_prefix_string);
restart_pending = shutdown_pending = 0;
do { /* restart-pending */
if (!is_graceful) {
ap_restart_time = time(NULL);
}
! copy_listeners(pconf);
ap_clear_pool(pconf);
pparent = ap_make_sub_pool(pconf);
--- 6117,6139 ----
start_mutex = ap_create_mutex(signal_prefix_string);
restart_pending = shutdown_pending = 0;
+ /* Create a thread for listening to WM_QUERYENDSESSION messages.
+ * This is necessary on Win9x only, as the SetConsoleCtrlHandler
+ * function does not work properly for Win9x
+ */
+ if ( get_platform_id() == VER_PLATFORM_WIN32_WINDOWS )
+ {
+ DWORD thread_id;
+
+ CreateThread( NULL, 0, WatchWindow, NULL, 0, &thread_id );
+ }
+
do { /* restart-pending */
if (!is_graceful) {
ap_restart_time = time(NULL);
}
! copy_listeners(pconf);
!
ap_clear_pool(pconf);
pparent = ap_make_sub_pool(pconf);
***************
*** 6158,6163 ****
--- 6285,6291 ----
return (0);
}
+
/*
* Send signal to a running Apache. On entry signal should contain
* either "shutdown" or "restart"
***************
*** 6248,6253 ****
--- 6376,6382 ----
char *s;
char *service_name = NULL;
int install = 0;
+ int run_as_service = 0;
int conf_specified = 0;
char *signal_to_send = NULL;
char cwd[MAX_STRING_LEN];
***************
*** 6309,6322 ****
ap_assert(start_mutex);
child = 1;
break;
! case 'n':
! service_name = ap_pstrdup(pcommands, optarg);
! if (isValidService(optarg)) {
! ap_registry_get_service_conf(pconf, ap_server_confname,
sizeof(ap_server_confname),
! optarg);
! conf_specified = 1;
! }
! break;
case 'i':
install = 1;
break;
--- 6438,6454 ----
ap_assert(start_mutex);
child = 1;
break;
! case 'n':
! service_name = ap_pstrdup(pcommands, optarg);
! if (isValidService(optarg)) {
! ap_registry_get_service_conf(pconf,
ap_server_confname, sizeof(ap_server_confname),
!
optarg);
! conf_specified = 1;
! }
! break;
! case 's':
! run_as_service = 1;
! break;
case 'i':
install = 1;
break;
***************
*** 6450,6456 ****
if (!child && !ap_dump_settings) {
ap_log_pid(pconf, ap_pid_fname);
! }
post_parse_init();
--- 6582,6588 ----
if (!child && !ap_dump_settings) {
ap_log_pid(pconf, ap_pid_fname);
! }
post_parse_init();
***************
*** 6458,6465 ****
printf("%s running...\n", ap_get_server_version());
#endif
#ifdef WIN32
if (!child) {
! printf("%s running...\n", ap_get_server_version());
}
#endif
if (one_process && !exit_event)
--- 6590,6609 ----
printf("%s running...\n", ap_get_server_version());
#endif
#ifdef WIN32
+ if (run_as_service) {
+ /* Close the bloody console window, if you can...
+ *
+ * At first I did this in the getopt switch statement,
+ * but this caused problems with the file handles:
+ * all output for access.log ended up in error.log.
+ */
+ FreeConsole();
+ }
if (!child) {
! /* Let's go fishing for some signals */
! SetConsoleCtrlHandler( ap_control_handler, TRUE );
!
! printf("%s running...\n", ap_get_server_version());
}
#endif
if (one_process && !exit_event)
***************
*** 6472,6485 ****
* exits, it spawns off a new one
*/
if (child || one_process) {
! if (!exit_event || !start_mutex)
! exit(-1);
! worker_main();
! ap_destroy_mutex(start_mutex);
! destroy_event(exit_event);
! }
! else
! master_main(argc, argv);
clean_parent_exit(0);
return 0; /* purely to avoid a warning */
--- 6616,6635 ----
* exits, it spawns off a new one
*/
if (child || one_process) {
! if (!exit_event || !start_mutex) {
! exit(-1);
! }
! worker_main();
! ap_destroy_mutex(start_mutex);
! destroy_event(exit_event);
! } else {
! if (run_as_service) {
! /* service_main will call master_main ! */
! service_main(master_main, argc, argv);
! } else {
! master_main(argc, argv);
! }
! }
clean_parent_exit(0);
return 0; /* purely to avoid a warning */
*** os/win32/service-old.c Thu Apr 08 16:04:48 1999
--- os/win32/service.c Wed Oct 06 15:46:12 1999
***************
*** 32,60 ****
static int ap_start_service(SC_HANDLE);
static int ap_stop_service(SC_HANDLE);
int service_main(int (*main_fn)(int, char **), int argc, char **argv )
{
! SERVICE_TABLE_ENTRY dispatchTable[] =
! {
! { "", service_main_fn },
! { NULL, NULL }
! };
!
! globdat.main_fn = main_fn;
! globdat.stop_event = create_event(0, 0, "apache-signal");
! 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");
! return(globdat.exit_status);
! }
! else
! {
! return(globdat.exit_status);
! }
}
void service_cd()
--- 32,128 ----
static int ap_start_service(SC_HANDLE);
static int ap_stop_service(SC_HANDLE);
+ DWORD platform_id = -1;
+
+ DWORD get_platform_id( void )
+ {
+ OSVERSIONINFO os_info;
+
+ if (platform_id == -1) {
+ /* Get the platform identifier */
+ os_info.dwOSVersionInfoSize = sizeof(os_info);
+
+ if (GetVersionEx(&os_info)) {
+ platform_id = os_info.dwPlatformId;
+ }
+ }
+
+ return platform_id;
+ }
+
int service_main(int (*main_fn)(int, char **), int argc, char **argv )
{
! /*
! printf( "Start of service_main:\n main_fn = %p\n", main_fn );
! */
!
! switch ( get_platform_id() ) {
! case VER_PLATFORM_WIN32_NT:
! /* Windows NT */
! {
! SERVICE_TABLE_ENTRY dispatchTable[] =
! {
! { "", service_main_fn },
! { NULL, NULL }
! };
!
! globdat.main_fn = main_fn;
! globdat.stop_event = create_event(0, 0,
"apache-signal");
! 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");
! return(globdat.exit_status);
! } else {
! return(globdat.exit_status);
! }
! break;
! }
! case VER_PLATFORM_WIN32_WINDOWS:
! /* Windows 95/98 */
! {
! HINSTANCE kerneldll;
! DWORD (WINAPI *RegisterService)(DWORD, DWORD);
!
! /* Obtain a handle to the kernel library */
! kerneldll = LoadLibrary( "KERNEL32.DLL" );
! if ( kerneldll == NULL ) {
! break;
! }
!
! /* Find the RegisterServiceProcess function */
! RegisterService = (DWORD (WINAPI *)(DWORD, DWORD))
! GetProcAddress( kerneldll,
"RegisterServiceProcess" );
! if ( RegisterService == NULL ) {
! break;
! }
!
! /* Register this process as a service */
! if ( ! RegisterService( (DWORD)NULL, 1 ) ) {
! break;
! }
!
! /* Run the service */
! globdat.exit_status = main_fn( argc, argv );
!
! /* When the service quits, remove it from the
! system service table */
! RegisterService( (DWORD)NULL, 0 );
!
! /* Free the kernel library */
! FreeLibrary( kerneldll );
!
! /* We have to quit right here to avoid an invalid
page fault */
! exit( globdat.exit_status );
!
! break;
! }
! }
! /* We should never get here... */
! return( -1 );
}
void service_cd()
***************
*** 123,129 ****
{
// Stop the service.
//
! case SERVICE_CONTROL_STOP:
state = SERVICE_STOP_PENDING;
ap_start_shutdown();
break;
--- 191,197 ----
{
// Stop the service.
//
! case SERVICE_CONTROL_STOP:
state = SERVICE_STOP_PENDING;
ap_start_shutdown();
break;
***************
*** 185,329 ****
return(1);
}
void InstallService(char *service_name, char *conf)
{
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
-
TCHAR szPath[512];
- TCHAR szQuotedPath[512];
printf("Installing the %s service to use %s\n", service_name, conf);
! if (GetModuleFileName( NULL, szPath, 512 ) == 0)
! {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"GetModuleFileName failed");
return;
}
! ap_snprintf(szQuotedPath, 512, "\"%s\"", szPath);
!
! 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
! service_name, // name of service
! service_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
! szQuotedPath, // 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 */
! if(!ap_registry_set_service_conf(conf, service_name))
! printf("The %s service has been installed
successfully.\n", service_name );
! }
! else {
! ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "CreateService failed");
! }
!
! CloseServiceHandle(schSCManager);
! }
}
void RemoveService(char *service_name)
{
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
-
printf("Removing the %s service\n", service_name);
! 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, service_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 */
! ap_stop_service(schService);
!
! // now remove the service
! if (DeleteService(schService) == 0)
! ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "DeleteService failed");
! else
! printf("The %s service has been removed successfully.\n",
service_name );
! CloseServiceHandle(schService);
! }
! /* SCM removes registry parameters */
! CloseServiceHandle(schSCManager);
! }
!
}
/* A hack to determine if we're running as a service without waiting for
! * the SCM to fail; if AllocConsole succeeds, we're a service.
*/
BOOL isProcessService() {
! if( !AllocConsole() )
! return FALSE;
! FreeConsole();
! return TRUE;
}
/* Determine is service_name is a valid service
*/
! BOOL isValidService(char *service_name) {
! SC_HANDLE schSCM, schSVC;
! int Err;
!
! if (!(schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) {
! ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "OpenSCManager failed");
! return FALSE;
! }
!
! if ((schSVC = OpenService(schSCM, service_name, SERVICE_ALL_ACCESS)))
{
! CloseServiceHandle(schSVC);
! CloseServiceHandle(schSCM);
! return TRUE;
! }
!
! Err = GetLastError();
! if (Err != ERROR_SERVICE_DOES_NOT_EXIST && Err != ERROR_INVALID_NAME)
! ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "OpenService failed");
! return FALSE;
}
int send_signal_to_service(char *service_name, char *sig) {
--- 253,496 ----
return(1);
}
+
void InstallService(char *service_name, char *conf)
{
TCHAR szPath[512];
printf("Installing the %s service to use %s\n", service_name, conf);
! if (GetModuleFileName( NULL, szPath, 512 ) == 0) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
"GetModuleFileName failed");
return;
}
! switch ( get_platform_id() )
! {
! case VER_PLATFORM_WIN32_NT:
! /* Windows NT */
! {
! TCHAR szQuotedPath[512];
! SC_HANDLE schService;
! SC_HANDLE schSCManager;
!
! ap_snprintf(szQuotedPath, 512, "\"%s\"", szPath);
!
! 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
!
service_name, // name of service
!
service_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
!
szQuotedPath, // 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 */
!
if(!ap_registry_set_service_conf(conf, service_name)) {
! printf("The %s service has
been installed successfully.\n", service_name );
! }
! } else {
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
!
"CreateService failed");
! }
!
! CloseServiceHandle(schSCManager);
! }
!
! break;
! }
! case VER_PLATFORM_WIN32_WINDOWS:
! /* Windows 95/98 */
! {
! TCHAR szServicePath[512];
! HKEY runservices;
!
! ap_snprintf(szServicePath, 512, "%s -s", szPath);
!
! /* Create/Find the RunServices key */
! if ( RegCreateKey (HKEY_LOCAL_MACHINE,
!
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
! &runservices ) != ERROR_SUCCESS ) {
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "Could not
create/find RunServices registry key");
! break;
! }
!
! /* Attempt to add a key for our service */
! if (RegSetValueEx(runservices,
! service_name,
! 0,
! REG_SZ,
! (unsigned char
*)szServicePath,
! strlen(
szServicePath )+1
! ) !=
ERROR_SUCCESS) {
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "Unable to install
service: Could not add registry key");
! RegCloseKey( runservices );
! break;
! }
!
! RegCloseKey( runservices );
!
! /* Now store the server_root in the registry */
! if ( !ap_registry_set_service_conf( conf,
service_name ) ) {
! printf("The %s service has been installed
successfully.\n", service_name );
! }
!
! break;
! }
! }
}
void RemoveService(char *service_name)
{
printf("Removing the %s service\n", service_name);
! switch ( get_platform_id() )
! {
! case VER_PLATFORM_WIN32_NT:
! /* Windows NT */
! {
! 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,
service_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 */
! ap_stop_service(schService);
!
! /* now remove the service */
! if (DeleteService(schService) == 0)
{
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
!
"DeleteService failed");
! } else {
! printf("The %s service has
been removed successfully.\n", service_name );
! }
!
! CloseServiceHandle(schService);
! }
! /* SCM removes registry parameters */
! CloseServiceHandle(schSCManager);
! }
!
! break;
! }
! case VER_PLATFORM_WIN32_WINDOWS:
! /* Windows 95/98 */
! {
! HKEY runservices;
!
! /* Open the RunServices key */
! if (RegOpenKey(HKEY_LOCAL_MACHINE,
!
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
! &runservices) !=
ERROR_SUCCESS) {
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "Could not open
RunServices registry key");
! } else {
! /* Delete the registry key for this service
*/
! if ( RegDeleteValue( runservices,
service_name ) != ERROR_SUCCESS ) {
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "Unable to
remove service: Could not delete registry key");
! }
!
! RegCloseKey(runservices);
! }
!
! break;
! }
! }
}
/* A hack to determine if we're running as a service without waiting for
! * the SCM to fail:
! if we can't get a handle for stdin, then we're a service.
*/
BOOL isProcessService() {
! HANDLE h;
!
! h = GetStdHandle( STD_INPUT_HANDLE );
! return( h == INVALID_HANDLE_VALUE );
}
/* Determine is service_name is a valid service
*/
! BOOL isValidService(char *service_name)
! {
! switch ( get_platform_id() )
! {
! case VER_PLATFORM_WIN32_NT:
! /* Windows NT */
! {
! SC_HANDLE schSCM, schSVC;
! int Err;
!
! if (!(schSCM = OpenSCManager(NULL, NULL,
SC_MANAGER_ALL_ACCESS)))
! {
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "OpenSCManager
failed");
! return FALSE;
! }
!
! if ((schSVC = OpenService(schSCM, service_name,
SERVICE_ALL_ACCESS)))
! {
! CloseServiceHandle(schSVC);
! CloseServiceHandle(schSCM);
! return TRUE;
! }
!
! Err = GetLastError();
! if (Err != ERROR_SERVICE_DOES_NOT_EXIST && Err !=
ERROR_INVALID_NAME)
! ap_log_error(APLOG_MARK,
APLOG_ERR|APLOG_WIN32ERROR, NULL,
! "OpenService
failed");
!
! break;
! }
! case VER_PLATFORM_WIN32_WINDOWS:
! /* Windows 95/98 */
! {
! /* I couldn't think of a valid check... */
! return TRUE;
! break;
! }
! }
! return FALSE;
}
int send_signal_to_service(char *service_name, char *sig) {
*** os/win32/service-old.h Thu Apr 08 16:04:48 1999
--- os/win32/service.h Fri Sep 24 11:34:32 1999
***************
*** 3,8 ****
--- 3,9 ----
#define SERVICE_H
#ifdef WIN32
+ DWORD get_platform_id( void );
int service_main(int (*main_fn)(int, char **), int argc, char **argv);
void service_set_status(int status);
void service_cd();
Re: [PATCH] Several patches for running Apache 1.3.9 on Win95
Posted by Bill Stoddard <st...@raleigh.ibm.com>.
Thanks for your contribution. Always good to see some fellow Apache for
Windows developers :-). Not sure when I can get around to reviewing these
(spending most of my time doing Apache 2.0 development), but I will update
the STATUS file with your patches so we will not loose track of them.
Bill