diff options
author | unknown <reggie@fedora.(none)> | 2005-07-20 10:55:40 -0500 |
---|---|---|
committer | unknown <reggie@fedora.(none)> | 2005-07-20 10:55:40 -0500 |
commit | 875b0e6322df380b6fcd4bd4f66d0d3e0142039f (patch) | |
tree | fd59532b923e8ee6c5bb48afac93f8d93e48fec6 /server-tools/instance-manager/WindowsService.cpp | |
parent | 6ae060305541019882bcb60bf086458b010faa45 (diff) | |
download | mariadb-git-875b0e6322df380b6fcd4bd4f66d0d3e0142039f.tar.gz |
initial import of Windows port of IM.
server-tools/instance-manager/commands.cc:
type cleanups for compiling on Windows
now using Options::config_file for the location of the single
my.cnf file we are using
server-tools/instance-manager/guardian.cc:
pthread_mutex_lock and unlock do not return a value on Windows
so we return 0 in all cases
server-tools/instance-manager/instance.cc:
big changes here.
Had to implement Windows versions of launch_and_wait and kill()
server-tools/instance-manager/instance.h:
added some function defs
server-tools/instance-manager/instance_map.cc:
pthread_mutex_lock and unlock do not return a value on Windows
Also, now using only the file named as Options::config_file
server-tools/instance-manager/instance_options.h:
added reference to port.h
server-tools/instance-manager/listener.cc:
reworked and simplified the socket handling code.
Added windows versions of the code that sets the sockets to be
non-blocking and non-inheritable
server-tools/instance-manager/listener.h:
change Options to always be a struct. Really surprised GCC was
letting this go. Options was declared to be struct in some places
and class in other places.
server-tools/instance-manager/log.cc:
added reference to port.h
server-tools/instance-manager/manager.cc:
moved all the signal code inside some #ifndef __WIN__ blocks
server-tools/instance-manager/manager.h:
change Options to always be a struct. Really surprised GCC was
letting this go. Options was declared to be struct in some places
and class in other places.
server-tools/instance-manager/mysqlmanager.cc:
added in the Windows service code.
server-tools/instance-manager/options.cc:
Added in the windows options for running as a service and the code
for loading settings only from a single file
server-tools/instance-manager/options.h:
added definitions for the new Windows service vars and routines
server-tools/instance-manager/parse_output.cc:
added reference to port.h
server-tools/instance-manager/priv.cc:
added reference to port.h
server-tools/instance-manager/priv.h:
linuxthreads should not be visible on Windows
server-tools/instance-manager/thread_registry.cc:
more __WIN__ blocking
server-tools/instance-manager/user_map.cc:
fixed passwd file code to handle files with \r\n line endings
server-tools/instance-manager/IMService.cpp:
New BitKeeper file ``server-tools/instance-manager/IMService.cpp''
server-tools/instance-manager/IMService.h:
New BitKeeper file ``server-tools/instance-manager/IMService.h''
server-tools/instance-manager/WindowsService.cpp:
New BitKeeper file ``server-tools/instance-manager/WindowsService.cpp''
server-tools/instance-manager/WindowsService.h:
New BitKeeper file ``server-tools/instance-manager/WindowsService.h''
server-tools/instance-manager/mysqlmanager.vcproj:
New BitKeeper file ``server-tools/instance-manager/mysqlmanager.vcproj''
server-tools/instance-manager/port.h:
New BitKeeper file ``server-tools/instance-manager/port.h''
Diffstat (limited to 'server-tools/instance-manager/WindowsService.cpp')
-rwxr-xr-x | server-tools/instance-manager/WindowsService.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/server-tools/instance-manager/WindowsService.cpp b/server-tools/instance-manager/WindowsService.cpp new file mode 100755 index 00000000000..851ac9beac8 --- /dev/null +++ b/server-tools/instance-manager/WindowsService.cpp @@ -0,0 +1,200 @@ +#include <windows.h> +#include <assert.h> +#include ".\windowsservice.h" + +static WindowsService *gService; + +WindowsService::WindowsService(void) +: statusCheckpoint(0), serviceName(NULL), inited(false), + dwAcceptedControls(SERVICE_ACCEPT_STOP) +{ + gService = this; + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + status.dwServiceSpecificExitCode = 0; +} + +WindowsService::~WindowsService(void) +{ +} + +BOOL WindowsService::Install() +{ + bool ret_val=false; + SC_HANDLE newService; + SC_HANDLE scm; + + if (IsInstalled()) return true; + + // determine the name of the currently executing file + char szFilePath[_MAX_PATH]; + GetModuleFileName(NULL, szFilePath, sizeof(szFilePath)); + + // open a connection to the SCM + if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE))) + return false; + + newService = CreateService(scm, serviceName, displayName, + SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, szFilePath, + NULL, NULL, NULL, username, password); + + if (newService) + { + CloseServiceHandle(newService); + ret_val = true; + } + + CloseServiceHandle(scm); + return ret_val; +} + +BOOL WindowsService::Init() +{ + assert(serviceName != NULL); + + if (inited) return true; + + SERVICE_TABLE_ENTRY stb[] = + { + { (LPSTR)serviceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, + { NULL, NULL } + }; + inited = true; + return StartServiceCtrlDispatcher(stb); //register with the Service Manager +} + +BOOL WindowsService::Remove() +{ + bool ret_val = false; + + if (! IsInstalled()) + return true; + + // open a connection to the SCM + SC_HANDLE scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE); + if (! scm) + return false; + + SC_HANDLE service = OpenService(scm, serviceName, DELETE); + if (service) + { + if (DeleteService(service)) + ret_val = true; + DWORD dw = ::GetLastError(); + CloseServiceHandle(service); + } + + CloseServiceHandle(scm); + return ret_val; +} + +BOOL WindowsService::IsInstalled() +{ + BOOL ret_val = FALSE; + + SC_HANDLE scm = ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + SC_HANDLE serv_handle = ::OpenService(scm, serviceName, SERVICE_QUERY_STATUS); + + ret_val = serv_handle != NULL; + + ::CloseServiceHandle(serv_handle); + ::CloseServiceHandle(scm); + + return ret_val; +} + +void WindowsService::SetAcceptedControls(DWORD acceptedControls) +{ + dwAcceptedControls = acceptedControls; +} + + +BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint, DWORD dwError) +{ + if(debugging) return TRUE; + + if(currentState == SERVICE_START_PENDING) + status.dwControlsAccepted = 0; + else + status.dwControlsAccepted = dwAcceptedControls; + + status.dwCurrentState = currentState; + status.dwWin32ExitCode = dwError != 0 ? ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR; + status.dwWaitHint = waitHint; + status.dwServiceSpecificExitCode = dwError; + + if(currentState == SERVICE_RUNNING || currentState == SERVICE_STOPPED) + { + status.dwCheckPoint = 0; + statusCheckpoint = 0; + } + else + status.dwCheckPoint = ++statusCheckpoint; + + // Report the status of the service to the service control manager. + BOOL result = SetServiceStatus(statusHandle, &status); + if (!result) + Log("ReportStatus failed"); + + return result; +} + +void WindowsService::RegisterAndRun(DWORD argc, LPTSTR *argv) +{ + statusHandle = ::RegisterServiceCtrlHandler(serviceName, ControlHandler); + if (statusHandle && ReportStatus(SERVICE_START_PENDING)) + Run(); + ReportStatus(SERVICE_STOPPED); +} + +void WindowsService::HandleControlCode(DWORD opcode) +{ + // Handle the requested control code. + switch(opcode) + { + case SERVICE_CONTROL_STOP: + // Stop the service. + status.dwCurrentState = SERVICE_STOP_PENDING; + Stop(); + break; + + case SERVICE_CONTROL_PAUSE: + status.dwCurrentState = SERVICE_PAUSE_PENDING; + Pause(); + break; + + case SERVICE_CONTROL_CONTINUE: + status.dwCurrentState = SERVICE_CONTINUE_PENDING; + Continue(); + break; + + case SERVICE_CONTROL_SHUTDOWN: + Shutdown(); + break; + + case SERVICE_CONTROL_INTERROGATE: + ReportStatus(status.dwCurrentState); + break; + + default: + // invalid control code + break; + } +} + +void WINAPI WindowsService::ServiceMain(DWORD argc, LPTSTR *argv) +{ + assert(gService != NULL); + + // register our service control handler: + gService->RegisterAndRun(argc, argv); +} + +void WINAPI WindowsService::ControlHandler(DWORD opcode) +{ + assert(gService != NULL); + + return gService->HandleControlCode(opcode); +} + + |