Added optional NT service and fix the TZ variable bug
mysys/my_init.c: Fix the TZ variable bug: 100% CPU usage sql/mysqld.cc: Added optional NT service sql/nt_servc.cc: Added optional NT service sql/nt_servc.h: Added optional NT service
This commit is contained in:
parent
74b73109c1
commit
2e6dff75ad
@ -219,6 +219,10 @@ static void my_win_init(void)
|
|||||||
|
|
||||||
setlocale(LC_CTYPE, ""); /* To get right sortorder */
|
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 */
|
/* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0,
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0,
|
||||||
KEY_READ,&hSoftMysql) != ERROR_SUCCESS)
|
KEY_READ,&hSoftMysql) != ERROR_SUCCESS)
|
||||||
|
132
sql/mysqld.cc
132
sql/mysqld.cc
@ -175,7 +175,9 @@ static uint handler_count;
|
|||||||
static bool opt_enable_named_pipe = 0;
|
static bool opt_enable_named_pipe = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __WIN__
|
#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
|
#endif
|
||||||
|
|
||||||
/* Set prefix for windows binary */
|
/* Set prefix for windows binary */
|
||||||
@ -381,6 +383,7 @@ enum db_type default_table_type=DB_TYPE_MYISAM;
|
|||||||
#undef getpid
|
#undef getpid
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
HANDLE hEventShutdown;
|
HANDLE hEventShutdown;
|
||||||
|
static char *event_name;
|
||||||
#include "nt_servc.h"
|
#include "nt_servc.h"
|
||||||
static NTService Service; // Service object for WinNT
|
static NTService Service; // Service object for WinNT
|
||||||
#endif
|
#endif
|
||||||
@ -2120,63 +2123,126 @@ The server will not act as a slave.");
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WIN__
|
#if defined(__WIN__)
|
||||||
/* ------------------------------------------------------------------------
|
|
||||||
main and thread entry function for Win32
|
|
||||||
(all this is needed only to run mysqld as a service on WinNT)
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
int mysql_service(void *p)
|
int mysql_service(void *p)
|
||||||
{
|
{
|
||||||
win_main(Service.my_argc, Service.my_argv);
|
if (use_opt_args)
|
||||||
|
win_main(opt_argc, opt_argv);
|
||||||
|
else
|
||||||
|
win_main(Service.my_argc, Service.my_argv);
|
||||||
return 0;
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// check environment variable OS
|
if (Service.GetOS()) /* true NT family */
|
||||||
if (Service.GetOS()) // "OS" defined; Should be NT
|
|
||||||
{
|
{
|
||||||
if (argc == 2)
|
char file_path[FN_REFLEN];
|
||||||
{
|
my_path(file_path, argv[0], ""); /* Find name in path */
|
||||||
char path[FN_REFLEN];
|
fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */
|
||||||
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 (argc == 2)
|
||||||
{
|
{
|
||||||
Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
|
if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME,
|
||||||
|
file_path))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
if (Service.IsService(argv[1]))
|
||||||
else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
|
|
||||||
{
|
{
|
||||||
Service.Install(0,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 (argc == 3) /* install or remove any optional service */
|
||||||
|
{
|
||||||
|
/* 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;
|
return 0;
|
||||||
}
|
if (Service.IsService(argv[2]))
|
||||||
else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
|
|
||||||
{
|
{
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (argc == 1) // No arguments; start as a service
|
else if (argc == 4)
|
||||||
{
|
{
|
||||||
// init service
|
/*
|
||||||
start_mode = 1;
|
Install an optional service with optional config file
|
||||||
long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service);
|
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))
|
||||||
|
{
|
||||||
|
/* start the default service */
|
||||||
|
start_mode= 1;
|
||||||
|
event_name= "MySqlShutdown";
|
||||||
|
Service.Init(MYSQL_SERVICENAME, mysql_service);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Start as standalone server */
|
||||||
// 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()
|
|
||||||
|
|
||||||
Service.my_argc=argc;
|
Service.my_argc=argc;
|
||||||
Service.my_argv=argv;
|
Service.my_argv=argv;
|
||||||
mysql_service(NULL);
|
mysql_service(NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -426,7 +426,17 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)
|
|||||||
|
|
||||||
// open a connection to the SCM
|
// open a connection to the SCM
|
||||||
if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
|
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
|
else
|
||||||
{
|
{
|
||||||
if (OperationType == 1)
|
if (OperationType == 1)
|
||||||
@ -479,3 +489,82 @@ If this condition persist, reboot the machine and try again\n");
|
|||||||
|
|
||||||
return ret_value;
|
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;
|
||||||
|
}
|
||||||
|
@ -52,7 +52,9 @@ class NTService
|
|||||||
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
|
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
|
||||||
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
|
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
|
||||||
BOOL Remove(LPCSTR szInternName);
|
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
|
void Stop(void); //to be called from app. to stop service
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user