diff options
Diffstat (limited to 'sql/nt_servc.cc')
-rw-r--r-- | sql/nt_servc.cc | 449 |
1 files changed, 195 insertions, 254 deletions
diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 2e7f2fc9c93..6930800982e 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -53,11 +53,12 @@ NTService::NTService() -------------------------------------------------------------------------- */ NTService::~NTService() { - if(ServiceName != NULL) delete[] ServiceName; + if (ServiceName != NULL) delete[] ServiceName; } /* ------------------------------------------------------------------------ -------------------------------------------------------------------------- */ + BOOL NTService::GetOS() { bOsNT = FALSE; @@ -71,12 +72,14 @@ BOOL NTService::GetOS() 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) { @@ -94,6 +97,8 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread) return StartServiceCtrlDispatcher(stb); //register with the Service Manager } + + /* ------------------------------------------------------------------------ Install() - Installs the service with Service manager nError values: @@ -101,9 +106,13 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread) 1 Can't open the Service manager 2 Failed to create service -------------------------------------------------------------------------- */ -BOOL NTService::Install(int startType, LPCSTR szInternName,LPCSTR szDisplayName, - LPCSTR szFullPath, LPCSTR szAccountName,LPCSTR szPassword) + +BOOL NTService::Install(int startType, LPCSTR szInternName, + LPCSTR szDisplayName, + LPCSTR szFullPath, LPCSTR szAccountName, + LPCSTR szPassword) { + BOOL ret_val=FALSE; SC_HANDLE newService, scm; if (!SeekStatus(szInternName,1)) @@ -112,49 +121,40 @@ BOOL NTService::Install(int startType, LPCSTR szInternName,LPCSTR szDisplayName, char szFilePath[_MAX_PATH]; GetModuleFileName(NULL, szFilePath, sizeof(szFilePath)); - // open a connection to the SCM - scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE); - - if (!scm) + if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE))) + printf("Failed to install the service (Couldn't open the SCM)\n"); + else // Install the new service { - printf("Failed to install the service\n" - "Problems to open the SCM"); - CloseServiceHandle(scm); - return FALSE; - } - else // Install the new service - { newService = CreateService( - scm, - szInternName, - szDisplayName, - dwDesiredAccess, //default: SERVICE_ALL_ACCESS - dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS - (startType == 1 ? SERVICE_AUTO_START : SERVICE_DEMAND_START), //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) + if (!(newService= + CreateService(scm, + szInternName, + szDisplayName, + dwDesiredAccess,//default: SERVICE_ALL_ACCESS + dwServiceType, //default: SERVICE_WIN32_OWN_PROCESS + //default: SERVICE_AUTOSTART + (startType == 1 ? SERVICE_AUTO_START : + SERVICE_DEMAND_START), + dwErrorControl, //default: SERVICE_ERROR_NORMAL + szFullPath, //exec full path + szLoadOrderGroup, //default: NULL + lpdwTagID, //default: NULL + szDependencies, //default: NULL + szAccountName, //default: NULL + szPassword))) //default: NULL + printf("Failed to install the service (Couldn't create service)\n"); + else { - printf("Failed to install the service.\n" - "Problems to create the service."); - CloseServiceHandle(scm); - CloseServiceHandle(newService); - return FALSE; + printf("Service successfully installed.\n"); + CloseServiceHandle(newService); + ret_val=TRUE; // Everything went ok } - else - printf("Service successfully installed.\n"); - } - CloseServiceHandle(scm); - CloseServiceHandle(newService); - return TRUE; - + CloseServiceHandle(scm); + } + return ret_val; } + + /* ------------------------------------------------------------------------ Remove() - Removes the service nError values: @@ -163,9 +163,10 @@ BOOL NTService::Install(int startType, LPCSTR szInternName,LPCSTR szDisplayName, 2 Failed to locate service 3 Failed to delete service -------------------------------------------------------------------------- */ + BOOL NTService::Remove(LPCSTR szInternName) { - + BOOL ret_value=FALSE; SC_HANDLE service, scm; if (!SeekStatus(szInternName,0)) @@ -174,44 +175,28 @@ BOOL NTService::Remove(LPCSTR szInternName) nError=0; // open a connection to the SCM - scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE); - - if (!scm) + if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE))) { - printf("Failed to remove the service\n" - "Problems to open the SCM"); - CloseServiceHandle(scm); - return FALSE; + printf("Failed to remove the service (Couldn't open the SCM)\n"); } else { - //open the service - service = OpenService(scm,szInternName, DELETE ); - if(service) + if ((service = OpenService(scm,szInternName, DELETE))) { - if(!DeleteService(service)) - { + if (!DeleteService(service)) printf("Failed to remove the service\n"); - CloseServiceHandle(service); - CloseServiceHandle(scm); - return FALSE; - } else + { printf("Service successfully removed.\n"); - } - else - { - printf("Failed to remove the service\n"); - printf("Problems to open the service\n"); + ret_value=TRUE; // everything went ok + } CloseServiceHandle(service); - CloseServiceHandle(scm); - return FALSE; } + else + printf("Failed to remove the service (Couldn't open the service)\n"); + CloseServiceHandle(scm); } - - CloseServiceHandle(service); - CloseServiceHandle(scm); - return TRUE; + return ret_value; } /* ------------------------------------------------------------------------ @@ -229,80 +214,66 @@ void NTService::Stop(void) 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; - } + if (!(pService->hServiceStatusHandle = + RegisterServiceCtrlHandler(pService->ServiceName, + (LPHANDLER_FUNCTION) + NTService::ServiceCtrlHandler))) + goto error; // notify SCM of progress - if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000)) - { - pService->Exit(GetLastError()); - return; - } + if (!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 1, 8000)) + goto error; // create the exit event - pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0); - if(!pService->hExitEvent) - { - pService->Exit(GetLastError()); - return; - } + if (!(pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0))) + goto error; - if(!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3, pService->nStartTimeOut)) - { - pService->Exit(GetLastError()); - return; - } + if (!pService->SetStatus(SERVICE_START_PENDING,NO_ERROR, 0, 3, + pService->nStartTimeOut)) + goto error; // save start arguments pService->my_argc=argc; pService->my_argv=argv; // start the service - if(!pService->StartService()) - { - pService->Exit(GetLastError()); - return; - } + if (!pService->StartService()) + goto error; - // the service is now running. - if(!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0)) - { - pService->Exit(GetLastError()); - return; - } + // Check that the service is now running. + if (!pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0)) + goto error; // wait for exit event WaitForSingleObject (pService->hExitEvent, INFINITE); // wait for thread to exit - if (WaitForSingleObject (pService->hThreadHandle, 1000)==WAIT_TIMEOUT) + if (WaitForSingleObject (pService->hThreadHandle, 1000) == WAIT_TIMEOUT) CloseHandle(pService->hThreadHandle); pService->Exit(0); + return; + +error: + pService->Exit(GetLastError()); + return; } /* ------------------------------------------------------------------------ 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; - + if (!(hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0, + (void *) this))) + return FALSE; bRunning = TRUE; return TRUE; } @@ -314,7 +285,7 @@ void NTService::StopService() bRunning=FALSE; // Set the event for application - if(hShutdownEvent) + if (hShutdownEvent) SetEvent(hShutdownEvent); // Set the event for ServiceMain @@ -325,113 +296,119 @@ void NTService::StopService() -------------------------------------------------------------------------- */ void NTService::PauseService() { - bPause = TRUE; - SuspendThread(hThreadHandle); + bPause = TRUE; + SuspendThread(hThreadHandle); } /* ------------------------------------------------------------------------ -------------------------------------------------------------------------- */ void NTService::ResumeService() { - bPause=FALSE; - ResumeThread(hThreadHandle); + bPause=FALSE; + ResumeThread(hThreadHandle); } /* ------------------------------------------------------------------------ -------------------------------------------------------------------------- */ BOOL NTService::SetStatus (DWORD dwCurrentState,DWORD dwWin32ExitCode, - DWORD dwServiceSpecificExitCode,DWORD dwCheckPoint,DWORD dwWaitHint) + DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, + DWORD dwWaitHint) { BOOL bRet; SERVICE_STATUS serviceStatus; - dwState=dwCurrentState; - - serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - serviceStatus.dwCurrentState = dwCurrentState; + dwState=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; + serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + serviceStatus.dwCurrentState = dwCurrentState; - // 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; + if (dwCurrentState == SERVICE_START_PENDING) + serviceStatus.dwControlsAccepted = 0; //don't accept control events + else + serviceStatus.dwControlsAccepted = (SERVICE_ACCEPT_STOP | + SERVICE_ACCEPT_PAUSE_CONTINUE | + SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; + // 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.dwCheckPoint = dwCheckPoint; - serviceStatus.dwWaitHint = dwWaitHint; + serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; - // Pass the status to the Service Manager - bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus); + serviceStatus.dwCheckPoint = dwCheckPoint; + serviceStatus.dwWaitHint = dwWaitHint; - if(!bRet) StopService(); + // Pass the status to the Service Manager + if (!(bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus))) + StopService(); - return bRet; + return bRet; } /* ------------------------------------------------------------------------ -------------------------------------------------------------------------- */ void NTService::ServiceCtrlHandler(DWORD ctrlCode) { + DWORD dwState; - DWORD dwState = 0; - - if(!pService) return; + if (!pService) + return; dwState=pService->dwState; // get current state - switch(ctrlCode) - { + 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; +#ifdef NOT_USED /* 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; +#endif + + 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); + if (hExitEvent) + CloseHandle(hExitEvent); // Send a message to the scm to tell that we stop if (hServiceStatusHandle) - SetStatus(SERVICE_STOPPED, error,0, 0, 0); + SetStatus(SERVICE_STOPPED, error,0, 0, 0); // If the thread has started kill it ??? // if (hThreadHandle) CloseHandle(hThreadHandle); @@ -441,100 +418,64 @@ void NTService::Exit(DWORD error) /* ------------------------------------------------------------------------ -------------------------------------------------------------------------- */ + BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType) { + BOOL ret_value=FALSE; 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 */ - { + if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE))) printf("There is a problem with the Service Control Manager!\n"); - CloseServiceHandle(scm); - return FALSE; - } - - if (OperationType == 1) /* an install operation */ + else { - service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ); - if(service) + if (OperationType == 1) { - ConfigBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096); - printf("The service already exists!\n"); - if ( QueryServiceConfig(service,ConfigBuf,4096,&dwSize) ) + /* an install operation */ + if ((service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ))) { - printf("The current server installed: %s\n", ConfigBuf->lpBinaryPathName); + LPQUERY_SERVICE_CONFIG ConfigBuf; + DWORD dwSize; + + 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(service); } - 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; + else + ret_value=TRUE; } - - memset(&ss, 0, sizeof(ss)); - k = QueryServiceStatus(service,&ss); - if (k) + else { - 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; - } + /* a remove operation */ + if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ))) + printf("The service doesn't exists!\n"); else { - CloseServiceHandle(scm); + SERVICE_STATUS ss; + + memset(&ss, 0, sizeof(ss)); + if (QueryServiceStatus(service,&ss)) + { + DWORD dwState = ss.dwCurrentState; + if (dwState == SERVICE_RUNNING) + printf("Failed to remove the service because the service is running\nStop the service and try again\n"); + else if (dwState == SERVICE_STOP_PENDING) + printf("\ +Failed to remove the service because the service is in stop pending state!\n\ +Wait 30 seconds and try again.\n\ +If this condition persist, reboot the machine and try again\n"); + else + ret_value= TRUE; + } CloseServiceHandle(service); - return TRUE; } - } - else - { - CloseServiceHandle(scm); - CloseServiceHandle(service); - } - } - - return FALSE; - + } + CloseServiceHandle(scm); + } + return ret_value; } -/* ------------------------- the end -------------------------------------- */ |