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/07 17:41:39 UTC

[PATCH] Several patches for running Apache 1.3.9 on Win95: Whoooo ops!

Sorry about this, I just discovered an error in the patch I posted (it
caused Apache as a service on Windows NT to fail. 

I tried to be smart and rewrite the isProcessService routine. 
Shouldn't have tried to be smart :-(

If you take out this "fix" then everything is working A-OK on WinNT 4.0SP5;
the strange thing is, I tested it some time ago on SP3 (my IT department
upgraded it to SP5 later on) and I could have *SWORN* it was working with my
fix....

Again, I'm terribly sorry about this, I should have checked my code better
before submitting it.

Regards,

JJ Keijser
UNIX System & Porting Engineer
Logica Inc.

Here's a new "diff -C3" for service.c:

*** service-old.c	Thu Apr 08 16:04:48 1999
--- service.c	Thu Oct 07 10:39:00 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,129 ----
  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;
--- 192,198 ----
      {
          // Stop the service.
          //
! 		case SERVICE_CONTROL_STOP:
              state = SERVICE_STOP_PENDING;
  	    ap_start_shutdown();
              break;
***************
*** 185,291 ****
      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
--- 254,447 ----
      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
***************
*** 303,329 ****
   */
  
  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) {
--- 459,501 ----
   */
  
  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) {