summaryrefslogtreecommitdiff
path: root/sql/nt_servc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/nt_servc.cc')
-rw-r--r--sql/nt_servc.cc400
1 files changed, 400 insertions, 0 deletions
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc
new file mode 100644
index 00000000000..5884300fe95
--- /dev/null
+++ b/sql/nt_servc.cc
@@ -0,0 +1,400 @@
+/* ------------------------------------------------------------------------
+ Windows NT Service class library
+ Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
+ This file is public domain and comes with NO WARRANTY of any kind
+ -------------------------------------------------------------------------- */
+#include <windows.h>
+#include <process.h>
+#include "nt_servc.h"
+
+
+static NTService *pService;
+
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+NTService::NTService()
+{
+
+ bOsNT = FALSE;
+ //service variables
+ ServiceName = NULL;
+ hExitEvent = 0;
+ bPause = FALSE;
+ bRunning = FALSE;
+ hThreadHandle = 0;
+ fpServiceThread = NULL;
+
+ //time-out variables
+ nStartTimeOut = 15000;
+ nStopTimeOut = 15000;
+ nPauseTimeOut = 5000;
+ nResumeTimeOut = 5000;
+
+ //install variables
+ dwDesiredAccess = SERVICE_ALL_ACCESS;
+ dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ dwStartType = SERVICE_AUTO_START;
+ dwErrorControl = SERVICE_ERROR_NORMAL;
+ szLoadOrderGroup = NULL;
+ lpdwTagID = NULL;
+ szDependencies = NULL;
+
+ my_argc = 0;
+ my_argv = NULL;
+ hShutdownEvent = 0;
+ nError = 0;
+ dwState = 0;
+}
+
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+NTService::~NTService()
+{
+ if(ServiceName != NULL) delete[] ServiceName;
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+BOOL NTService::GetOS()
+{
+ bOsNT = FALSE;
+ memset(&osVer, 0, sizeof(OSVERSIONINFO));
+ osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (GetVersionEx(&osVer))
+ {
+ if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ bOsNT = TRUE;
+ }
+ return bOsNT;
+}
+
+/* ------------------------------------------------------------------------
+ Init() Registers the main service thread with the service manager
+
+ ServiceThread - pointer to the main programs entry function
+ when the service is started
+ -------------------------------------------------------------------------- */
+long NTService::Init(LPCSTR szInternName,void *ServiceThread)
+{
+
+ pService = this;
+
+ fpServiceThread = (THREAD_FC)ServiceThread;
+ ServiceName = new char[lstrlen(szInternName)+1];
+ lstrcpy(ServiceName,szInternName);
+
+ SERVICE_TABLE_ENTRY stb[] =
+ {
+ { (char *)szInternName,(LPSERVICE_MAIN_FUNCTION) ServiceMain} ,
+ { NULL, NULL }
+ };
+
+ return StartServiceCtrlDispatcher(stb); //register with the Service Manager
+}
+/* ------------------------------------------------------------------------
+ Install() - Installs the service with Service manager
+ nError values:
+ 0 success
+ 1 Can't open the Service manager
+ 2 Failed to create service
+ -------------------------------------------------------------------------- */
+BOOL NTService::Install(LPCSTR szInternName,LPCSTR szDisplayName,
+ LPCSTR szFullPath, LPCSTR szAccountName,LPCSTR szPassword)
+{
+ SC_HANDLE newService, scm;
+
+ nError=0;
+
+ // open a connection to the SCM
+ scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
+ if(scm) // Install the new service
+ { newService = CreateService(
+ scm,
+ szInternName,
+ szDisplayName,
+ dwDesiredAccess, //default: SERVICE_ALL_ACCESS
+ dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS
+ dwStartType, //default: SERVICE_AUTOSTART
+ dwErrorControl, //default: SERVICE_ERROR_NORMAL
+ szFullPath, //exec full path
+ szLoadOrderGroup, //default: NULL
+ lpdwTagID, //default: NULL
+ szDependencies, //default: NULL
+ szAccountName, //default: NULL
+ szPassword); //default: NULL
+
+ if (newService) CloseServiceHandle(newService); // clean up
+ else nError=2;
+
+ // clean up
+ CloseServiceHandle(scm);
+ }
+ else nError=1;
+
+ return (!nError);
+}
+/* ------------------------------------------------------------------------
+ Remove() - Removes the service
+ nError values:
+ 0 success
+ 1 Can't open the Service manager
+ 2 Failed to locate service
+ 3 Failed to delete service
+ -------------------------------------------------------------------------- */
+BOOL NTService::Remove(LPCSTR szInternName)
+{
+
+ SC_HANDLE service, scm;
+
+ nError=0;
+
+ // open a connection to the SCM
+ scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
+
+ if (scm)
+ {
+ //open the service
+ service = OpenService(scm,szInternName, DELETE );
+ if(service)
+ {
+ if(!DeleteService(service)) nError=3;
+ CloseServiceHandle(service);
+ }
+ else
+ {
+ //MessageBox(NULL,"Can't find the service","Remove Error",MB_OK|MB_ICONHAND);
+ nError=2;
+ }
+ CloseServiceHandle(scm);
+ }
+ else nError=1;
+
+ return (!nError);
+}
+
+/* ------------------------------------------------------------------------
+ Stop() - this function should be called before the app. exits to stop
+ the service
+ -------------------------------------------------------------------------- */
+void NTService::Stop(void)
+{
+ SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, 60000);
+ StopService();
+ SetStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 1000);
+}
+
+/* ------------------------------------------------------------------------
+ ServiceMain() - This is the function that is called from the
+ service manager to start the service
+ -------------------------------------------------------------------------- */
+void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
+{
+
+ // registration function
+ pService->hServiceStatusHandle =
+ RegisterServiceCtrlHandler(pService->ServiceName,
+ (LPHANDLER_FUNCTION )NTService::ServiceCtrlHandler);
+
+ if(!pService->hServiceStatusHandle)
+ {
+ pService->Exit(GetLastError());
+ return;
+ }
+
+ // notify SCM of progress
+ if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000))
+ {
+ pService->Exit(GetLastError());
+ return;
+ }
+
+ // create the exit event
+ pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0);
+ if(!pService->hExitEvent)
+ {
+ pService->Exit(GetLastError());
+ return;
+ }
+
+ if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3, pService->nStartTimeOut))
+ {
+ pService->Exit(GetLastError());
+ return;
+ }
+
+ // save start arguments
+ pService->my_argc=argc;
+ pService->my_argv=argv;
+
+ // start the service
+ if(!pService->StartService())
+ {
+ pService->Exit(GetLastError());
+ return;
+ }
+
+ // the service is now running.
+ if(!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0))
+ {
+ pService->Exit(GetLastError());
+ return;
+ }
+
+ // wait for exit event
+ WaitForSingleObject (pService->hExitEvent, INFINITE);
+
+ // wait for thread to exit
+ WaitForSingleObject (pService->hThreadHandle, 30000);
+
+ pService->Exit(0);
+}
+
+/* ------------------------------------------------------------------------
+ StartService() - starts the appliaction thread
+ -------------------------------------------------------------------------- */
+BOOL NTService::StartService()
+{
+
+ // Start the real service's thread (application)
+ hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,(void *)this);
+
+ if (hThreadHandle==0) return FALSE;
+
+ bRunning = TRUE;
+ return TRUE;
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+void NTService::StopService()
+{
+ bRunning=FALSE;
+
+ // Set the event for application
+ if(hShutdownEvent)
+ SetEvent(hShutdownEvent);
+
+ // Set the event for ServiceMain
+ SetEvent(hExitEvent);
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+void NTService::PauseService()
+{
+ bPause = TRUE;
+ SuspendThread(hThreadHandle);
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+void NTService::ResumeService()
+{
+ bPause=FALSE;
+ ResumeThread(hThreadHandle);
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+BOOL NTService::SetStatus (DWORD dwCurrentState,DWORD dwWin32ExitCode,
+ DWORD dwServiceSpecificExitCode,DWORD dwCheckPoint,DWORD dwWaitHint)
+{
+ BOOL bRet;
+ SERVICE_STATUS serviceStatus;
+
+ dwState=dwCurrentState;
+
+ serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ serviceStatus.dwCurrentState = dwCurrentState;
+
+ if (dwCurrentState == SERVICE_START_PENDING)
+ serviceStatus.dwControlsAccepted = 0; //don't accept conrol events
+ else
+ serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
+ SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
+
+ // if a specific exit code is defined,set up the win32 exit code properly
+ if (dwServiceSpecificExitCode == 0)
+ serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
+ else
+ serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+
+ serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
+
+ serviceStatus.dwCheckPoint = dwCheckPoint;
+ serviceStatus.dwWaitHint = dwWaitHint;
+
+ // Pass the status to the Service Manager
+ bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus);
+
+ if(!bRet) StopService();
+
+ return bRet;
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+void NTService::ServiceCtrlHandler(DWORD ctrlCode)
+{
+
+ DWORD dwState = 0;
+
+ if(!pService) return;
+
+ dwState=pService->dwState; // get current state
+
+ switch(ctrlCode)
+ {
+
+ /*********** do we need this ? *******************************
+ case SERVICE_CONTROL_PAUSE:
+ if (pService->bRunning && ! pService->bPause)
+ {
+ dwState = SERVICE_PAUSED;
+ pService->SetStatus(SERVICE_PAUSE_PENDING,NO_ERROR, 0, 1, pService->nPauseTimeOut);
+ pService->PauseService();
+ }
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ if (pService->bRunning && pService->bPause)
+ {
+ dwState = SERVICE_RUNNING;
+ pService->SetStatus(SERVICE_CONTINUE_PENDING,NO_ERROR, 0, 1, pService->nResumeTimeOut);
+ pService->ResumeService();
+ }
+ break;
+ ****************************************************************/
+
+ case SERVICE_CONTROL_SHUTDOWN:
+ case SERVICE_CONTROL_STOP:
+ dwState = SERVICE_STOP_PENDING;
+ pService->SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, pService->nStopTimeOut);
+ pService->StopService();
+ break;
+
+ default:
+ pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
+ break;
+ }
+ //pService->SetStatus(dwState, NO_ERROR,0, 0, 0);
+}
+/* ------------------------------------------------------------------------
+
+ -------------------------------------------------------------------------- */
+void NTService::Exit(DWORD error)
+{
+ if (hExitEvent) CloseHandle(hExitEvent);
+
+ // Send a message to the scm to tell that we stop
+ if (hServiceStatusHandle)
+ SetStatus(SERVICE_STOPPED, error,0, 0, 0);
+
+ // If the thread has started kill it ???
+ // if (hThreadHandle) CloseHandle(hThreadHandle);
+
+}
+
+/* ------------------------- the end -------------------------------------- */