mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			586 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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 "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;
 | 
						|
}
 |