枚举NT services

类别:VC语言 点击:0 评论:0 推荐:

                                                枚举NT services
       闻怡洋·vchelp

  下面的文章提供了访问NT中所有Service的功能,每次列举Services时,函数会返回一个列表。 列表的内容依赖于你所使用的参数。 (我认为这是一种很巧妙的编程方法,它极大的减轻了数据和函数的冗余,利用一个STATIC函数来产生本身对象的列表或者是来产生对象)

  Class declaration:声明

  class TTrixServiceInfo {

  public:

   CString ServiceName;

   CString DisplayName;

   CString BinaryPath;

   DWORD ServiceType;

   DWORD StartType;

   DWORD ErrorControl;

   DWORD CurrentState;

  public:

   TTrixServiceInfo();

   TTrixServiceInfo& operator=(const TTrixServiceInfo& source);

   CString GetServiceType(void);

   CString GetStartType(void);

   CString GetErrorControl(void);

   CString GetCurrentState(void);

   static TTrixServiceInfo *EnumServices(DWORD serviceType,

   DWORD serviceState,DWORD *count);

  };

Description:类的每一个实例都包含了SERVICE的各种信息,如果想得到SERVICE的列表,请调用TTrixServiceInfo::EnumServices(...)。

参数ServiceType的取值可能是:SERVICE_WIN32 and SERVICE_DRIVER.

参数ServiceState的取值可能是:SERVICE_ACTIVE and SERVICE_INACTIVE.

EnumServices(...)将返回TTrixServiceInfo对象的列表,(如果出错返回NULL)。列表中对象的个数可以通过参数返回时得到。
下面是具体的代码:

  TTrixServiceInfo *lpservice = NULL;

  DWORD count;

  lpservice =           TTrixServiceInfo::EnumServices(SERVICE_WIN32,SERVICE_ACTIVE|SERVICE_INACTIVE,&count/*得到个数*/);

  if (lpservice) {//如果正确

    for (DWORD index = 0; index < count; index ++) {

     printf("%d. %s, %s\n", index, lpservice[index].DisplayName,

     lpservice[index].GetCurrentState());

     }

    delete [] lpservice;

   }

  Source code:

  TTrixServiceInfo::TTrixServiceInfo()

  {

   ServiceName.Empty();

   DisplayName.Empty();

   BinaryPath.Empty();

   ServiceType = 0;

   StartType = 0;

   ErrorControl = 0;

   CurrentState = 0;

  }

  TTrixServiceInfo& TTrixServiceInfo::operator=(const TTrixServiceInfo& source)

  {

   ServiceName = source.ServiceName;

   DisplayName = source.DisplayName;

   BinaryPath = source.BinaryPath;

   ServiceType = source.ServiceType;

   StartType = source.StartType;

   ErrorControl = source.ErrorControl;

   CurrentState = source.CurrentState;

   return *this;

  }

  CString TTrixServiceInfo::GetServiceType(void)

  {

   // Winnt.h

   CString str = "UNKNOWN";

   if (ServiceType & SERVICE_WIN32) {

    if (ServiceType &

     SERVICE_WIN32_OWN_PROCESS)

     str = "WIN32_OWN_PROCESS";

    else if (ServiceType &

     SERVICE_WIN32_SHARE_PROCESS)

     str = "WIN32_SHARE_PROCESS";

    if (ServiceType &

      SERVICE_INTERACTIVE_PROCESS)

      str += "(INTERACTIVE_PROCESS)";

    }

     switch (ServiceType) {

      case SERVICE_KERNEL_DRIVER:

        str = "KERNEL_DRIVER"; break;

      case SERVICE_FILE_SYSTEM_DRIVER:

        str = "FILE_SYSTEM_DRIVER";

        break;

      };

    return str;

   }

  CString TTrixServiceInfo::GetStartType(void)

  {

   // Winnt.h

   TCHAR *types[] = {

   "BOOT_START", // 0

   "SYSTEM_START", // 1

   "AUTO_START", // 2

   "DEMAND_START", // 3

   "DISABLED" // 4

  };

  return CString(types[StartType]);

  }

  CString TTrixServiceInfo::GetErrorControl(void)

  {

   // Winnt.h

   TCHAR *types[] = {

   "ERROR_IGNORE", // 0

   "ERROR_NORMAL", // 1

   "ERROR_SEVERE", // 2

   "ERROR_CRITICAL" // 3

   };

  return CString(types[ErrorControl]);

  }

  CString TTrixServiceInfo::GetCurrentState(void)

  {

   // Winsvc.h

   TCHAR *types[] = {

   "UNKNOWN",

   "STOPPED", // 1

   "START_PENDING", // 2

   "STOP_PENDING", // 3

   "RUNNING", // 4

   "CONTINUE_PENDING", // 5

   "PAUSE_PENDING", // 6

   "PAUSED" // 7

   };

   return CString(types[CurrentState]);

  }

  // ServiceType = bit OR of SERVICE_WIN32, SERVICE_DRIVER

  // ServiceState = bit OR of SERVICE_ACTIVE, SERVICE_INACTIVE

  TTrixServiceInfo *TTrixServiceInfo::EnumServices(DWORD serviceType,DWORD

  serviceState,DWORD *count)

  {

   // Maybe check if serviceType and serviceState have at least one constant specified

   *count = 0;

   TTrixServiceInfo *info = NULL;

   SC_HANDLE scman = ::OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE);

   if (scman) {

    ENUM_SERVICE_STATUS service, *lpservice;

    BOOL rc;

    DWORD bytesNeeded,servicesReturned,resumeHandle = 0;

    rc = ::EnumServicesStatus(scman,serviceType,serviceState,&service,sizeof(service),

       &bytesNeeded,&servicesReturned,&resumeHandle);

    if ((rc == FALSE) && (::GetLastError() == ERROR_MORE_DATA)) {

     DWORD bytes = bytesNeeded + sizeof(ENUM_SERVICE_STATUS);

     lpservice = new ENUM_SERVICE_STATUS [bytes];

          ::EnumServicesStatus(scman,serviceType,serviceState,lpservice,bytes,

          &bytesNeeded,&servicesReturned,&resumeHandle);

     *count = servicesReturned; // Not a chance that 0 services is returned

     info = new TTrixServiceInfo [servicesReturned];

  TCHAR Buffer[1024];

  // Should be enough for service info

  QUERY_SERVICE_CONFIG *lpqch = (QUERY_SERVICE_CONFIG*)Buffer;

  for (DWORD ndx = 0; ndx < servicesReturned; ndx++) {

    info[ndx].ServiceName = lpservice[ndx].lpServiceName;

    info[ndx].DisplayName = lpservice[ndx].lpDisplayName;

    info[ndx].ServiceType = lpservice[ndx].ServiceStatus.dwServiceType;

    info[ndx].CurrentState = lpservice[ndx].ServiceStatus.dwCurrentState;

    SC_HANDLE sh = ::OpenService(scman,lpservice[ndx].lpServiceName,SERVICE_QUERY_CONFIG);

    if (::QueryServiceConfig(sh,lpqch,sizeof(Buffer),&bytesNeeded)) {

     info[ndx].BinaryPath = lpqch->lpBinaryPathName;

     info[ndx].StartType = lpqch->dwStartType;

     info[ndx].ErrorControl = lpqch->dwErrorControl;

    }

    ::CloseServiceHandle(sh);

   }

   delete [] lpservice;

   }

   ::CloseServiceHandle(scman);

   }

   return info;

  }

 

本文地址:http://com.8s8s.com/it/it3556.htm