mariadb/sql/nt_servc.cc
Vladislav Vaintroub bc76ad8f6b WL#5161 : Cross-platform build with CMake
BUILD-CMAKE:
  WL#5161 : Documentation on how to build with CMake on Unix/Windows
BUILD/Makefile.am:
  Add new file
BUILD/autorun.sh:
  WL#5161 : use choose_configure instead of autotools configure script
  (choose configure will call cmake if cmake is available)
BUILD/choose_configure.sh:
  WL#5161 : use choose_configure instead of autotools configure script
  (choose configure will call cmake if cmake is available)
CMakeLists.txt:
  WL#5161 : Rewrite top-level CMakeLists.txt. 
  Remove  Windows specifics
  - compiler flags handling moved to configure.cmake
  - storage engine/plugin stuff moved into cmake/plugin.cmake
  - copy docs
Makefile.am:
  Added new files
client/CMakeLists.txt:
  WL#5161 : Rewrite CMakeLists.txt to be platform-independent
  Handle packagng (add INSTALL commands)
cmake/Makefile.am:
  WL#5161 : use choose_configure instead of autotools configure script
  (choose configure will call cmake if cmake is available)
cmake/abi_check.cmake:
  Custom targets for abi_check (for cmake)
cmake/bison.cmake:
  - Check bison availability
  - Add RUN_BISON macro (used to create sql_yacc.cc and sql_yacc.h)
cmake/cat.cmake:
  Add helper script to concatenate files.
cmake/character_sets.cmake:
  Handle configuration parameters WITH_EXTRA_CHARSETS
cmake/check_minimal_version.cmake:
  Helper script to check the minimum required version of cmake
cmake/configure.pl:
  Add perl script to convert ./configure parameters for cmake
cmake/create_initial_db.cmake.in:
  Add script helper to create initial database. 
  (on Windows, we pack initial db with the redistribution
  package)
cmake/do_abi_check.cmake:
  Perform abi check
cmake/dtrace.cmake:
  Handle dtrace in CMake Build.
  Check for dtrace availablility,
  run dtrace -G on solaris in prelink step
cmake/dtrace_prelink.cmake:
  Run dtrace -G on Solaris in pre-link step,
  link the object it creates together with library or
  executable
cmake/install_macros.cmake:
  Helper macros for packaging
  (install pdb on Windows, install symlinks on Unix)
cmake/make_dist.cmake.in:
  "make dist" - 
  - pack autotools ./configure script with the source
  (renamed to configure.am)
  - pack bison output
cmake/merge_archives_unix.cmake.in:
  script to merge static libraries on Unix
cmake/misc.cmake:
  Build helper macros
  - MERGE_STATIC_LIBS 
  We use it when building client library and embedded
  (avoid recompilation)
  
  - Convert source file paths to absolute names.
  We use it in  to locate files of a different project,
  when the files need to be recompiled (e.g in embedded
  several storage engines are recompiled with 
  -DEMBEDDED_LIBRARY)
cmake/mysql_version.cmake:
  Extract version info from configure.in
  Handle package names.
cmake/plugin.cmake:
  Rewrote storage/mysql_storage_engine.cmake to handle 
  other types of plugins and do it in OS-independent manner.
cmake/readline.cmake:
  Macros to handle WITH_READLINE/WITH_LIBEDIT parameters
cmake/ssl.cmake:
  Add macros to handle WITH_SSL parameter.
cmake/stack_direction.c:
  Helper to check stack direction.
cmake/zlib.cmake:
  Add macros to handle WITH_ZLIB parameter
cmd-line-utils/libedit/CMakeLists.txt:
  Build libedit with cmake.
cmd-line-utils/libedit/Makefile.am:
  Add new file
cmd-line-utils/readline/CMakeLists.txt:
  Build readline with CMake.
cmd-line-utils/readline/Makefile.am:
  Add new file
config.h.cmake:
  WL#5161 : Add config.h template for cmake
configure.cmake:
  WL#5161 : Add platform tests ( for cmake)
configure.in:
  Added new subdirectories
dbug/CMakeLists.txt:
  WL#5161
extra/CMakeLists.txt:
  WL#5161
extra/yassl/CMakeLists.txt:
  WL#5161
extra/yassl/taocrypt/CMakeLists.txt:
  WL#5161
include/Makefile.am:
  Add new file
include/keycache.h:
  remove configure-win.h and remove HUGE_PTR defined there.
include/my_global.h:
  use my_config.h for Windows, not config-win.h anymore
include/my_pthread.h:
  - Move thread_safe_increment from config-win.h to other headers
  (config-win.h is not used anymore)
  - Declare pthread_cancel on Windows (it is used in daemon_example)
include/my_sys.h:
  Add malloc.h on Windows (we use -D_WIN32_LEAN_AND_MEAN now, and 
  with this define malloc.h is not included automatically via windows.h)
include/mysql/plugin.h:
  Handle pure-C plugins with Microsoft compiler.
include/thr_alarm.h:
  remove rf_SetTimer that used to be defined in config-win.h
  Replace with UINT_PTR (we do not use config-win.h anymore
  and typedef was needed in this single place only)
libmysql/CMakeLists.txt:
  Avoid pointless recompilation of source files 
  in client library if possible. Merge static 
  libs (dbug, mysys) to create static client 
  library.
libmysqld/CMakeLists.txt:
  Avoid pointless recompilation of source files 
  when building embedded. Instead, merge dbug and 
  mysys (and some other static libs) into embedded.
libmysqld/examples/CMakeLists.txt:
  Embedded compilation on Unix
libmysqld/lib_sql.cc:
  Do not define THD::clear_error() in lib_sql.cc
  for embedded. Instead, use the same inline 
  definition from sql_class.h as in none-embedded 
  case (fixes duplicate symbol errors on Windows
  and removes pointless #ifdef EMBEDDED)
man/CMakeLists.txt:
  Install man files.
man/Makefile.am:
  Add new file.
mysql-test/CMakeLists.txt:
  Install mysql-test files
mysql-test/Makefile.am:
  Add new files
mysql-test/lib/My/ConfigFactory.pm:
  Allow testing with mtr in out-of-source builds.
mysql-test/lib/My/Find.pm:
  the build configurations are now also available on Unix
  Xcode on Mac uses the Release, RelwithDebinfo and Debug 
  subdirectories for executables. Earlier, build configurations 
  were available only on Windows.
mysql-test/lib/My/SafeProcess.pm:
  Allow testing with mtr in out-of-source builds.
mysql-test/lib/My/SafeProcess/CMakeLists.txt:
  Port CMakeLists.txt to Unix
mysql-test/lib/My/SafeProcess/safe_kill_win.cc:
  add stdlib.h (to be able to compile with -DWIN32_LEAN_AND_MEAN)
mysql-test/lib/My/SafeProcess/safe_process_win.cc:
  Add stdlib.h (to be able to compile with -DWIN32_LEAN_AND_MEAN)
  define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE if not defined 
  (can happen using MinGW compiler that comes with old SDK)
mysql-test/mtr.out-of-source:
  Allow testing with mtr in out-of-source builds.
mysql-test/mysql-test-run.pl:
  Allow testing with mtr in out-of-source builds.
  Use common find_plugin macro for Windows and unix.
mysql-test/t/fulltext_plugin.test:
  This test can now run on Windows as well.
mysys/CMakeLists.txt:
  Port CMakeLists.txt to Unix
mysys/my_create.c:
  config-win.h is dead => NO_OPEN_3 is never defined.
mysys/my_getsystime.c:
  config-win.h is dead => define OFFSET_TO_EPOCH where it is used.
mysys/my_winthread.c:
  Add  win32 pthread_cancel - used by daemon_example
mysys/mysys_priv.h:
  config-win.h is dead => include <sys/stat.h> where it is used
  fix prototype of my_win_(f)stat
plugin/daemon_example/CMakeLists.txt:
  Compile daemon_example with CMake
plugin/daemon_example/Makefile.am:
  Add new file
plugin/fulltext/CMakeLists.txt:
  Compile full-text example with CMake
plugin/fulltext/Makefile.am:
  Add new file.
plugin/semisync/CMakeLists.txt:
  Fix semisync to use common  macro for plugins.
regex/CMakeLists.txt:
  Use absolute filenames, when adding regex library 
  (we recompile files in embedded, and want to locate 
  sources via GET_TARGET_PROPERTY( ... SOURCES ..))
regex/regex2.h:
  Remove pointless typedef (produces error with MinGW compiler)
scripts/CMakeLists.txt:
  Add configure/install for scripts
sql-bench/CMakeLists.txt:
  install sql-bench files
sql-bench/Makefile.am:
  Add new file
sql/CMakeLists.txt:
  Port CmakeLists.txt to Unix
sql/nt_servc.cc:
  compile server with -DWIN32_LEAN_AND_MEAN
sql/share/CMakeLists.txt:
  Install charsets
sql/share/Makefile.am:
  Add new file
sql/sql_builtin.cc.in:
  Handle pure-C plugins on Windows.
sql/sql_class.h:
  Use the same clear_error macro in embedded and not embedded.
  Fixes pointless #ifdef and avoids duplicate symbols when linking
  on Windows.
storage/Makefile.am:
  storage/mysql_storage_engine.cmake => cmake/plugin.cmake
storage/archive/CMakeLists.txt:
  Add names for static and dynamic plugin libraries.
  Link archive with zlib
storage/blackhole/CMakeLists.txt:
  Add names for static and dynamic storage 
  engine libraries
storage/csv/CMakeLists.txt:
  Add names for static and dynamic storage engine
  libraries
storage/example/CMakeLists.txt:
  Add names for static and dynamic storage engine 
  libraries
storage/federated/CMakeLists.txt:
  Add names for static and dynamic storage engine 
  libraries
storage/heap/CMakeLists.txt:
  Add names for static and dynamic storage engine 
  libraries
storage/ibmdb2i/CMakeLists.txt:
  Better port for ibmdb2i plugin
storage/innobase/CMakeLists.txt:
  Run system checks.
  
  Add names for static and dynamic storage engine 
  libraries.
storage/innobase/include/page0page.ic:
  Fix compile error on OpenSolaris.
storage/myisam/CMakeLists.txt:
  Port CmakeLists.txt to Unix
storage/myisammrg/CMakeLists.txt:
  Add names for static and dynamic storage engine 
  libraries
storage/mysql_storage_engine.cmake:
  storage/mysql_storage_engine.cmake => cmake/plugin.cmake
support-files/CMakeLists.txt:
  Configure and install some files from support-files.
support-files/Makefile.am:
  Add new file
tests/CMakeLists.txt:
  In general case, mysqlclient library can be dependent
  on C++ runtime(if it includes yassl and is not compiled
  with gcc or MSVC)
unittest/mysys/CMakeLists.txt:
  Add unit tests
unittest/mysys/Makefile.am:
  Add new file
unittest/mytap/CMakeLists.txt:
  Add library for unit tests
unittest/mytap/Makefile.am:
  Add new file
unittest/mytap/tap.c:
  fix function definitions to match declarations
win/create_def_file.js:
  Fix link error with intel compiler (icl 
  defines of special label for exception handler)
2009-11-09 12:32:48 +01:00

586 lines
15 KiB
C++

/**
@file
@brief
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 <stdio.h>
#include <stdlib.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 = 86400000;
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;
}
/**
Registers the main service thread with the service manager.
@param 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
}
/**
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(int startType, LPCSTR szInternName,
LPCSTR szDisplayName,
LPCSTR szFullPath, LPCSTR szAccountName,
LPCSTR szPassword)
{
BOOL ret_val=FALSE;
SC_HANDLE newService, scm;
if (!SeekStatus(szInternName,1))
return FALSE;
char szFilePath[_MAX_PATH];
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// open a connection to the 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
{
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("Service successfully installed.\n");
CloseServiceHandle(newService);
ret_val=TRUE; // Everything went ok
}
CloseServiceHandle(scm);
}
return ret_val;
}
/**
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)
{
BOOL ret_value=FALSE;
SC_HANDLE service, scm;
if (!SeekStatus(szInternName,0))
return FALSE;
nError=0;
// open a connection to the SCM
if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
{
printf("Failed to remove the service (Couldn't open the SCM)\n");
}
else
{
if ((service = OpenService(scm,szInternName, DELETE)))
{
if (!DeleteService(service))
printf("Failed to remove the service\n");
else
{
printf("Service successfully removed.\n");
ret_value=TRUE; // everything went ok
}
CloseServiceHandle(service);
}
else
printf("Failed to remove the service (Couldn't open the service)\n");
CloseServiceHandle(scm);
}
return ret_value;
}
/**
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);
}
/**
This is the function that is called from the
service manager to start the service.
*/
void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
{
// registration function
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))
goto error;
// create the exit event
if (!(pService->hExitEvent = CreateEvent (0, TRUE, FALSE,0)))
goto error;
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())
goto error;
// wait for exit event
WaitForSingleObject (pService->hExitEvent, INFINITE);
// wait for thread to exit
if (WaitForSingleObject (pService->hThreadHandle, INFINITE) == WAIT_TIMEOUT)
CloseHandle(pService->hThreadHandle);
pService->Exit(0);
return;
error:
pService->Exit(GetLastError());
return;
}
void NTService::SetRunning()
{
if (pService)
pService->SetStatus(SERVICE_RUNNING,NO_ERROR, 0, 0, 0);
}
/* ------------------------------------------------------------------------
StartService() - starts the application thread
-------------------------------------------------------------------------- */
BOOL NTService::StartService()
{
// Start the real service's thread (application)
if (!(hThreadHandle = (HANDLE) _beginthread((THREAD_FC)fpServiceThread,0,
(void *) this)))
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 control 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
if (!(bRet=SetServiceStatus (hServiceStatusHandle, &serviceStatus)))
StopService();
return bRet;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
void NTService::ServiceCtrlHandler(DWORD ctrlCode)
{
DWORD dwState;
if (!pService)
return;
dwState=pService->dwState; // get current state
switch(ctrlCode) {
#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);
// 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);
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType)
{
BOOL ret_value=FALSE;
SC_HANDLE service, scm;
// open a connection to the SCM
if (!(scm = OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
{
DWORD ret_error=GetLastError();
if (ret_error == ERROR_ACCESS_DENIED)
{
printf("Install/Remove of the Service Denied!\n");
if (!is_super_user())
printf("That operation should be made by an user with Administrator privileges!\n");
}
else
printf("There is a problem for to open the Service Control Manager!\n");
}
else
{
if (OperationType == 1)
{
/* an install operation */
if ((service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
{
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);
}
else
ret_value=TRUE;
}
else
{
/* a remove operation */
if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS )))
printf("The service doesn't exist!\n");
else
{
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);
}
}
CloseServiceHandle(scm);
}
return ret_value;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::IsService(LPCSTR ServiceName)
{
BOOL ret_value=FALSE;
SC_HANDLE service, scm;
if ((scm= OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE)))
{
if ((service = OpenService(scm,ServiceName, SERVICE_QUERY_STATUS)))
{
ret_value=TRUE;
CloseServiceHandle(service);
}
CloseServiceHandle(scm);
}
return ret_value;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::got_service_option(char **argv, char *service_option)
{
char *option;
for (option= argv[1]; *option; option++)
if (!strcmp(option, service_option))
return TRUE;
return FALSE;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::is_super_user()
{
HANDLE hAccessToken;
UCHAR InfoBuffer[1024];
PTOKEN_GROUPS ptgGroups=(PTOKEN_GROUPS)InfoBuffer;
DWORD dwInfoBufferSize;
PSID psidAdministrators;
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
UINT x;
BOOL ret_value=FALSE;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE,&hAccessToken ))
{
if (GetLastError() != ERROR_NO_TOKEN)
return FALSE;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken))
return FALSE;
}
ret_value= GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer,
1024, &dwInfoBufferSize);
CloseHandle(hAccessToken);
if (!ret_value )
return FALSE;
if (!AllocateAndInitializeSid(&siaNtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&psidAdministrators))
return FALSE;
ret_value = FALSE;
for (x=0;x<ptgGroups->GroupCount;x++)
{
if ( EqualSid(psidAdministrators, ptgGroups->Groups[x].Sid) )
{
ret_value = TRUE;
break;
}
}
FreeSid(psidAdministrators);
return ret_value;
}