Commit 03bf236f authored by miguel@light.local's avatar miguel@light.local

Adding code for NT service in the install and remove

routines for avoid to leave the Service Control Manager
in bad state. Print messages for to reduce the current
user errors when are trying to install or start the service.
Adding the option to install the service for manual start:
--install-manual.
parent 28f35b26
...@@ -5,3 +5,4 @@ serg@serg.mysql.com ...@@ -5,3 +5,4 @@ serg@serg.mysql.com
monty@work.mysql.com monty@work.mysql.com
sasha@mysql.sashanet.com sasha@mysql.sashanet.com
heikki@donna.mysql.fi heikki@donna.mysql.fi
miguel@light.local
...@@ -2052,15 +2052,19 @@ int main(int argc, char **argv) ...@@ -2052,15 +2052,19 @@ int main(int argc, char **argv)
if (Service.GetOS()) // "OS" defined; Should be NT if (Service.GetOS()) // "OS" defined; Should be NT
{ {
if (argc == 2) if (argc == 2)
{
if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
my_path(path, argv[0], ""); // Find name in path my_path(path, argv[0], ""); // Find name in path
fn_format(path,argv[0],path,"",1+4+16); // Force use of full path fn_format(path,argv[0],path,"",1+4+16); // Force use of full path
if (!Service.Install(MYSQL_SERVICENAME,MYSQL_SERVICENAME,path))
MessageBox(NULL,"Failed to install Service",MYSQL_SERVICENAME, if (!strcmp(argv[1],"-install") || !strcmp(argv[1],"--install"))
MB_OK|MB_ICONSTOP); {
Service.Install(1,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
return 0;
}
else if (!strcmp(argv[1],"-install-manual") || !strcmp(argv[1],"--install-manual"))
{
Service.Install(0,MYSQL_SERVICENAME,MYSQL_SERVICENAME,path);
return 0; return 0;
} }
else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove")) else if (!strcmp(argv[1],"-remove") || !strcmp(argv[1],"--remove"))
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#include <windows.h> #include <windows.h>
#include <process.h> #include <process.h>
#include <stdio.h>
#include "nt_servc.h" #include "nt_servc.h"
...@@ -100,23 +101,36 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread) ...@@ -100,23 +101,36 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
1 Can't open the Service manager 1 Can't open the Service manager
2 Failed to create service 2 Failed to create service
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName, BOOL NTService::Install(int startType, LPCSTR szInternName,LPCSTR szDisplayName,
LPCSTR szFullPath, LPCSTR szAccountName,LPCSTR szPassword) LPCSTR szFullPath, LPCSTR szAccountName,LPCSTR szPassword)
{ {
SC_HANDLE newService, scm; SC_HANDLE newService, scm;
nError=0; if (!SeekStatus(szInternName,1))
return FALSE;
char szFilePath[_MAX_PATH];
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// open a connection to the SCM // open a connection to the SCM
scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE); scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
if(scm) // Install the new service
if (!scm)
{
printf("Failed to install the service\n"
"Problems to open the SCM");
CloseServiceHandle(scm);
return FALSE;
}
else // Install the new service
{ newService = CreateService( { newService = CreateService(
scm, scm,
szInternName, szInternName,
szDisplayName, szDisplayName,
dwDesiredAccess, //default: SERVICE_ALL_ACCESS dwDesiredAccess, //default: SERVICE_ALL_ACCESS
dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS
dwStartType, //default: SERVICE_AUTOSTART (startType == 1 ? SERVICE_AUTO_START : SERVICE_DEMAND_START), //default: SERVICE_AUTOSTART
dwErrorControl, //default: SERVICE_ERROR_NORMAL dwErrorControl, //default: SERVICE_ERROR_NORMAL
szFullPath, //exec full path szFullPath, //exec full path
szLoadOrderGroup, //default: NULL szLoadOrderGroup, //default: NULL
...@@ -125,15 +139,21 @@ BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName, ...@@ -125,15 +139,21 @@ BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName,
szAccountName, //default: NULL szAccountName, //default: NULL
szPassword); //default: NULL szPassword); //default: NULL
if (newService) CloseServiceHandle(newService); // clean up if (!newService)
else nError=2; {
printf("Failed to install the service.\n"
// clean up "Problems to create the service.");
CloseServiceHandle(scm); CloseServiceHandle(scm);
CloseServiceHandle(newService);
return FALSE;
}
else
printf("Service successfully installed.\n");
} }
else nError=1; CloseServiceHandle(scm);
CloseServiceHandle(newService);
return TRUE;
return (!nError);
} }
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
Remove() - Removes the service Remove() - Removes the service
...@@ -148,30 +168,50 @@ BOOL NTService::Remove(LPCSTR szInternName) ...@@ -148,30 +168,50 @@ BOOL NTService::Remove(LPCSTR szInternName)
SC_HANDLE service, scm; SC_HANDLE service, scm;
if (!SeekStatus(szInternName,0))
return FALSE;
nError=0; nError=0;
// open a connection to the SCM // open a connection to the SCM
scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE); scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
if (scm) if (!scm)
{
printf("Failed to remove the service\n"
"Problems to open the SCM");
CloseServiceHandle(scm);
return FALSE;
}
else
{ {
//open the service //open the service
service = OpenService(scm,szInternName, DELETE ); service = OpenService(scm,szInternName, DELETE );
if(service) if(service)
{ {
if(!DeleteService(service)) nError=3; if(!DeleteService(service))
{
printf("Failed to remove the service\n");
CloseServiceHandle(service); CloseServiceHandle(service);
CloseServiceHandle(scm);
return FALSE;
} }
else else
{ printf("Service successfully removed.\n");
//MessageBox(NULL,"Can't find the service","Remove Error",MB_OK|MB_ICONHAND);
nError=2;
} }
else
{
printf("Failed to remove the service\n");
printf("Problems to open the service\n");
CloseServiceHandle(service);
CloseServiceHandle(scm); CloseServiceHandle(scm);
return FALSE;
}
} }
else nError=1;
return (!nError); CloseServiceHandle(service);
CloseServiceHandle(scm);
return TRUE;
} }
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
...@@ -398,4 +438,103 @@ void NTService::Exit(DWORD error) ...@@ -398,4 +438,103 @@ void NTService::Exit(DWORD error)
} }
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)
{
SC_HANDLE service, scm;
LPQUERY_SERVICE_CONFIG ConfigBuf;
DWORD dwSize;
SERVICE_STATUS ss;
DWORD dwState = 0xFFFFFFFF;
int k;
// open a connection to the SCM
scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
if (!scm) /* problems with the SCM */
{
printf("There is a problem with the Service Control Manager!\n");
CloseServiceHandle(scm);
return FALSE;
}
if (OperationType == 1) /* an install operation */
{
service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS );
if(service)
{
ConfigBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
printf("The service already exists!\n");
if ( QueryServiceConfig(service,ConfigBuf,4096,&dwSize) )
{
printf("The current server installed: %s\n", ConfigBuf->lpBinaryPathName);
}
LocalFree(ConfigBuf);
CloseServiceHandle(scm);
CloseServiceHandle(service);
return FALSE;
}
else
{
CloseServiceHandle(scm);
CloseServiceHandle(service);
return TRUE;
}
}
else /* a remove operation */
{
service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS );
if(!service)
{
printf("The service doesn't exists!\n");
CloseServiceHandle(scm);
CloseServiceHandle(service);
return FALSE;
}
memset(&ss, 0, sizeof(ss));
k = QueryServiceStatus(service,&ss);
if (k)
{
dwState = ss.dwCurrentState;
if (dwState == SERVICE_RUNNING )
{
printf("Failed to remove the service:\n");
printf("The service is running!\n"
"Stop the server and try again.");
CloseServiceHandle(service);
CloseServiceHandle(scm);
return FALSE;
}
else if (dwState == SERVICE_STOP_PENDING)
{
printf("Failed to remove the service:\n");
printf("The service is in stop pending state!\n"
"Wait 30 seconds and try again.\n"
"If this condition persist, reboot the machine\n"
"and try again");
CloseServiceHandle(service);
CloseServiceHandle(scm);
return FALSE;
}
else
{
CloseServiceHandle(scm);
CloseServiceHandle(service);
return TRUE;
}
}
else
{
CloseServiceHandle(scm);
CloseServiceHandle(service);
}
}
return FALSE;
}
/* ------------------------- the end -------------------------------------- */ /* ------------------------- the end -------------------------------------- */
...@@ -48,8 +48,9 @@ class NTService ...@@ -48,8 +48,9 @@ class NTService
//service install / un-install //service install / un-install
BOOL Install(LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath, BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath,
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL); LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName); BOOL Remove(LPCSTR szInternName);
void Stop(void); //to be called from app. to stop service void Stop(void); //to be called from app. to stop service
......
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