Commit 927472d0 authored by miguel@hegel.br's avatar miguel@hegel.br
Browse files

Added optional NT service and fix the TZ variable bug

parent 87351da2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -219,6 +219,10 @@ static void my_win_init(void)

  setlocale(LC_CTYPE, "");             /* To get right sortorder */

  /* Clear the OS system variable TZ and avoid the 100% CPU usage */
  _putenv( "TZ=" ); 
  _tzset();

  /* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0,
		   KEY_READ,&hSoftMysql) != ERROR_SUCCESS)
+98 −32
Original line number Diff line number Diff line
@@ -175,7 +175,9 @@ static uint handler_count;
static bool opt_enable_named_pipe = 0;
#endif
#ifdef __WIN__
static bool opt_console=0,start_mode=0;
static bool opt_console=0,start_mode=0, use_opt_args;
static int opt_argc;
static char **opt_argv;
#endif

/* Set prefix for windows binary */
@@ -381,6 +383,7 @@ enum db_type default_table_type=DB_TYPE_MYISAM;
#undef	 getpid
#include <process.h>
HANDLE hEventShutdown;
static char *event_name;
#include "nt_servc.h"
static	 NTService  Service;	      // Service object for WinNT
#endif
@@ -2120,63 +2123,126 @@ The server will not act as a slave.");
}


#ifdef __WIN__
/* ------------------------------------------------------------------------
   main and thread entry function for Win32
   (all this is needed only to run mysqld as a service on WinNT)
 -------------------------------------------------------------------------- */
#if defined(__WIN__)
int mysql_service(void *p)
{
  if (use_opt_args)
    win_main(opt_argc, opt_argv);
  else
    win_main(Service.my_argc, Service.my_argv);
  return 0;
}

/*
  Handle basic handling of services, like installation and removal

  SYNOPSIS
    default_service_handling()
    argv		Pointer to argument list 
    servicename		Internal name of service
    displayname		Display name of service (in taskbar ?)
    file_path		Path to this program

  RETURN VALUES
    0		option handled
    1		Could not handle option
 */

bool default_service_handling(char **argv,
			      const char *servicename,
			      const char *displayname,
			      const char *file_path)
{
  if (Service.got_service_option(argv, "install"))
  {
    Service.Install(1, servicename, displayname, file_path);
    return 0;
  }
  if (Service.got_service_option(argv, "install-manual"))
  {
    Service.Install(0, servicename, displayname, file_path);
    return 0;
  }
  if (Service.got_service_option(argv, "remove"))
  {
    Service.Remove(servicename);
    return 0;
  }
  return 1;
}


int main(int argc, char **argv)
{
  // check  environment variable OS
  if (Service.GetOS())	// "OS" defined; Should be NT
  if (Service.GetOS())	/* true NT family */
  {
    char file_path[FN_REFLEN];
    my_path(file_path, argv[0], "");		      /* Find name in path */
    fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */

    if (argc == 2)
    {	
      char path[FN_REFLEN];
      my_path(path, argv[0], "");		   // Find name in path
      fn_format(path,argv[0],path,"",1+4+16);    // Force use of full path

      if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
      if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME,
				   file_path))
	return 0;
      if (Service.IsService(argv[1]))
      {
	Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
        /* start an optional service */
        event_name=		argv[1];
	load_default_groups[0]= argv[1];
        start_mode= 1;
        Service.Init(event_name, mysql_service);
        return 0;
      }
      else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
    }
    else if (argc == 3) /* install or remove any optional service */
    {
        Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
      /* Add service name after filename */
      uint length=strlen(file_path);
      *strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
		argv[2], NullS)= '\0';

      if (!default_service_handling(argv, argv[2], argv[2], file_path))
	return 0;
      }
      else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
      if (Service.IsService(argv[2]))
      {
	Service.Remove(MYSQL_SERVICENAME);
	/* start an optional service */
	use_opt_args=1;
	opt_argc=argc;
	opt_argv=argv;
	event_name= argv[2];
	start_mode= 1;
	Service.Init(event_name, mysql_service);
	return 0;
      }
    }
    else if (argc == 1)		   // No arguments; start as a service
    else if (argc == 4)
    {
      /*
	Install an optional service with optional config file
	mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini
      */
      uint length=strlen(file_path);
      *strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
		argv[3], " ", argv[2], NullS)= '\0';
      if (!default_service_handling(argv, argv[2], argv[2], file_path))
	return 0;
    }
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
    {
      // init service
      /* start the default service */
      start_mode= 1;
      long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service);
      event_name= "MySqlShutdown";
      Service.Init(MYSQL_SERVICENAME, mysql_service);
      return 0;
    }
  }

  // This is a WIN95 machine or a start of mysqld as a standalone program
  // we have to pass the arguments, in case of NT-service this will be done
  // by ServiceMain()

  /* Start as standalone server */
  Service.my_argc=argc;
  Service.my_argv=argv;
  mysql_service(NULL);
  return 0;
}
/* ------------------------------------------------------------------------ */
#endif


+90 −1
Original line number Diff line number Diff line
@@ -426,7 +426,17 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)

  // open a connection to the SCM
  if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
    printf("There is a problem with the Service Control Manager!\n");
  {
    DWORD ret_error=GetLastError();
    if (ret_error == ERROR_ACCESS_DENIED)
    {
     printf("Install/Remove of the Service Denied!\n");
     if(!is_super_user())
      printf("That operation should be made by an user with Administrator privileges!\n");
    }
    else
     printf("There is a problem for to open the Service Control Manager!\n");
  }
  else
  {
    if (OperationType == 1)
@@ -479,3 +489,82 @@ If this condition persist, reboot the machine and try again\n");

  return ret_value;
}
/* ------------------------------------------------------------------------
 -------------------------------------------------------------------------- */
BOOL NTService::IsService(LPCSTR ServiceName)
{
  BOOL ret_value=FALSE;
  SC_HANDLE service, scm;
  
  if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE))
  {
    if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS )))
    {
      ret_value=TRUE;
      CloseServiceHandle(service);
    }
    CloseServiceHandle(scm);
  }
  return ret_value;
}
/* ------------------------------------------------------------------------
 -------------------------------------------------------------------------- */
BOOL NTService::got_service_option(char **argv, char *service_option)
{
  char *option;
  for (option= argv[1]; *option; option++)
    if (!strcmp(option, service_option))
      return TRUE;
  return FALSE;
}
/* ------------------------------------------------------------------------
 -------------------------------------------------------------------------- */
BOOL NTService::is_super_user()
{
  HANDLE hAccessToken;
  UCHAR InfoBuffer[1024];
  PTOKEN_GROUPS ptgGroups=(PTOKEN_GROUPS)InfoBuffer;
  DWORD dwInfoBufferSize;
  PSID psidAdministrators;
  SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  UINT x;
  BOOL ret_value=FALSE;
 
  if(!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,&hAccessToken ))
  {
   if(GetLastError() != ERROR_NO_TOKEN)
    return FALSE;
 
   if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken))
    return FALSE;
  }
 
  ret_value= GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer,
                                 1024, &dwInfoBufferSize);

  CloseHandle(hAccessToken);
 
  if(!ret_value )
   return FALSE;
 
  if(!AllocateAndInitializeSid(&siaNtAuthority, 2,
      SECURITY_BUILTIN_DOMAIN_RID,
      DOMAIN_ALIAS_RID_ADMINS,
      0, 0, 0, 0, 0, 0,
      &psidAdministrators))
      return FALSE;

  ret_value = FALSE;
 
  for(x=0;x<ptgGroups->GroupCount;x++)
  {
   if( EqualSid(psidAdministrators, ptgGroups->Groups[x].Sid) )
   {
    ret_value = TRUE;
    break;
   }
 
  }
  FreeSid(psidAdministrators);
  return ret_value;
}
+3 −1
Original line number Diff line number Diff line
@@ -52,7 +52,9 @@ class NTService
		    LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
    BOOL SeekStatus(LPCSTR szInternName, int OperationType);
    BOOL Remove(LPCSTR szInternName);

    BOOL IsService(LPCSTR ServiceName);
    BOOL got_service_option(char **argv, char *service_option);
    BOOL is_super_user();
    void Stop(void); //to be called from app. to stop service

  protected: