summaryrefslogtreecommitdiff
path: root/server-tools/instance-manager/WindowsService.cpp
diff options
context:
space:
mode:
authorunknown <reggie@fedora.(none)>2005-07-20 10:55:40 -0500
committerunknown <reggie@fedora.(none)>2005-07-20 10:55:40 -0500
commit875b0e6322df380b6fcd4bd4f66d0d3e0142039f (patch)
treefd59532b923e8ee6c5bb48afac93f8d93e48fec6 /server-tools/instance-manager/WindowsService.cpp
parent6ae060305541019882bcb60bf086458b010faa45 (diff)
downloadmariadb-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-xserver-tools/instance-manager/WindowsService.cpp200
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);
+}
+
+