INFO: IADsServiceOperations Requires Aministrative rights (328429)



The information in this article applies to:

  • the operating system: Microsoft Windows 2000
  • Microsoft Active Directory Services Interface, System Component
  • the operating system: Microsoft Windows XP
  • Microsoft Active Directory Services Interface, Microsoft Active Directory Client

This article was previously published under Q328429

SUMMARY

IADsServiceOperations requires that the user instantiating the interface have full control over the service being queried.

MORE INFORMATION

The IADsServiceOperations interface assumes that the caller has full access to all the service information. The interface opens the Service Manager database with full read/write/query privileges. If the object is running in a thread or process in a user context that does not have read/write/query privileges, the interface will fail to return the requested information.

One possible work around is to use the Service Manger APIs directly. Below is a simple console application that illustrates how one can determine if a service is running on a given client.

Only processes with Administrator privileges are able to open a database handle that can be used by the CreateService and LockServiceDatabase functions. The returned handle is only valid for the process that called the OpenSCManager function. It can be closed by calling the CloseServiceHandle function.

// servicestatus.cpp : Defines the entry point for the console application.
// 

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

// 
// Function stubs
// 
void GetServiceStatus( char *lpService, SC_HANDLE hSM );

int main(int argc, char* argv[])
{
   SC_HANDLE hSCM;
   // 
   // We are expecting at most two arguments at minimum, 1.
   // If only
   // one is present, then it is assumed that we are targeting
   // the local system and the first argument is the service we
   // want to get the status for.  
   // 
   // If two, then the first is the service we want the status of,
   // the second is the machine to target.
   // 
   if( argc == 2 ) 
   {
      // 
      // We have one argument.  Open the local SCM
      // 
      hSCM = OpenSCManager( NULL, NULL, GENERIC_READ);
      if( !hSCM ) 
      {
         // 
         // Error occured opening the local SCM, 
         // display an error and exit
         // 
         printf("Error Opening Service Control Manager : %0X\n", GetLastError());
         return 1;
      }
      // 
      // Display The Service Status
      // 
      GetServiceStatus( argv[1], hSCM );
      CloseServiceHandle( hSCM );
      return 0;
   }
   else if( argc == 3 )
   {
      // 
      // We have a target system, open the SCM on that system and display
      // the service status...
      // 
      hSCM = OpenSCManager( argv[2], NULL, GENERIC_READ);
      if( !hSCM ) 
      {
         // 
         // Error occured opening the local SCM, 
         // display an error and exit
         // 
         printf("Error Opening Service Control Manager  on %s : %0X\n", argv[2], GetLastError());
         return 1;
      }
      // 
      // Display the Service Status
      // 
      GetServiceStatus( argv[1], hSCM );
      CloseServiceHandle( hSCM );
      return 0;
   }
   else
   {
      printf("Wrong number of arguments\nMust have:\n");
      printf("command SERVICE_TO_CHECK [machine]\n");
      return 1;
   }
 
   return 0;
}

void GetServiceStatus( char *lpService, SC_HANDLE hSM )
{
   // 
   // lpService must be the name of the service, not the
   // display name in the Service Manager it is the 
   // actual name for the service.  You can get the service
   // name from by:
   // 1. Start Service Manager
   // 2. Right click the desired service, select properties from the menu
   // 3. On the GENERAL TAB, find the Service Name: moniker, the name to the
   //    right will be the service name recognized by the SC Manager
   // 
   SC_HANDLE hService;
   hService = OpenService( hSM, lpService, GENERIC_READ);
   if( hService )
   {
      // 
      // We have a handle to the service.
      // lets query for its status
      // 
      SERVICE_STATUS ssStatus;
      if( QueryServiceStatus( hService, &ssStatus) )
      {
         char Buffer[30];
         sprintf(Buffer,"%s","NO SERVICE STATUS DETECTED");
         switch( ssStatus.dwCurrentState )
         {
         case SERVICE_CONTINUE_PENDING: // The service continue is pending. 
            sprintf( Buffer,"%s", "SERVICE_CONTINUE_PENDING");
            break;
         case SERVICE_PAUSE_PENDING: // The service pause is pending. 
            sprintf( Buffer,"%s", "SERVICE_PAUSE_PENDING");
            break;
         case SERVICE_PAUSED: // The service is paused. 
            sprintf( Buffer,"%s","SERVICE_PAUSED");
            break;
         case SERVICE_RUNNING: // The service is running. 
            sprintf( Buffer,"%s", "SERVICE_RUNNING");
            break;
         case SERVICE_START_PENDING: // The service is starting. 
            sprintf( Buffer,"%s","SERVICE_START_PENDING");
            break;
         case SERVICE_STOP_PENDING: // The service is stopping. 
            sprintf( Buffer,"%s","SERVICE_STOP_PENDING");
            break;
         case SERVICE_STOPPED: // The  Service is stopped
            sprintf( Buffer,"%s","SERVICE_STOPPED");
            break;
         }
         printf("Service Status: %s\n", Buffer);
      }
      else
      {
         printf("Error retrieving service %s status: %0X\n", lpService, GetLastError());
      }
      CloseServiceHandle( hService );
   }
   else
   {
      printf("Error opening service %s : %0d\n", lpService, GetLastError());
   }
   
}
				

Modification Type:MajorLast Reviewed:2/12/2004
Keywords:kbDSWADSI2003Swept kbinfo KB328429 kbAudDeveloper