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

Added optional NT service and fix the TZ variable bug

parent 87351da2
......@@ -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)
......
......@@ -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)
{
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;
}
/*
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)
{
if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME,
file_path))
return 0;
if (Service.IsService(argv[1]))
{
/* 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 */
{
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
/* Add service name after filename */
uint length=strlen(file_path);
*strxnmov(file_path + length, sizeof(file_path)-length-2, " ",
argv[2], NullS)= '\0';
if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
{
Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
if (!default_service_handling(argv, argv[2], argv[2], file_path))
return 0;
}
else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
if (Service.IsService(argv[2]))
{
Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
/* 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 (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
{
Service.Remove(MYSQL_SERVICENAME);
}
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) // No arguments; start as a service
else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
{
// init service
start_mode = 1;
long tmp=Service.Init(MYSQL_SERVICENAME,mysql_service);
/* start the default service */
start_mode= 1;
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
......
......@@ -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;
}
......@@ -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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment