Enumerate NT Services 怡 洋 · vchelp
The following article provides a function of accessing all services in NT. Each time you enumerate Services, the function returns a list. The content of the list relies on the parameters you use. (I think this is a very clever programming method, which greatly reduces the redundancy of data and functions, using a Static function to generate a list of objects or to generate objects)
Class Declaration: Declaration
Class TtrixServiceInfo {
PUBLIC:
CString ServiceName;
CString DisplayName;
Cstring binarypath;
DWORD ServiceType;
DWORD STARTTYPE;
DWORD ERRORCONTROL;
DWORD CURRENTSTATE;
PUBLIC:
TTRIXSERVICEINFO ();
TtrixServiceInfo & Operator = (const ttrixserviceInfo);
CString GetServiceType (Void);
CString getStartType (void);
CString getErrorControl (void);
CString getCurrentState (void);
Static TtrixServiceInfo * EnumServices (DWORD ServiceType,
DWORD ServiceState, DWORD * Count);
}
Description: Each instance of the class contains various information of Service. If you want to get a list of service, call TtrixServiceInfo :: EnumServices (...).
The value of the parameter serviceType may be: service_win32 and service_driver.
The value of the parameter serviceState may be: Service_Active and service_inactive.
EnumServices (...) will return a list of TTRIXServiceInfo objects (if an error returns null). The number of objects in the list can be obtained when the parameter is returned. Here is the specific code:
TtrixServiceInfo * lpservice = null;
DWORD count;
LPSERVICE = TtrixServiceInfo :: enumservices (service_win32, service_active | service_inactive, & count / * Get a number * /);
IF (lpservice) {// if it is correct
For (DWORD INDEX = 0; 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_oen_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 (service) { 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 * type [] = { "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 * type [] = { "Error_Ignore", // 0 "Error_NORMAL", // 1 "Error_severe", // 2 "Error_Critical" // 3 } Return CString (Types [ErrorControl]); } CSTRING TTRIXSERVICEINFO :: getCurrentState (void) { // Winsvc.h Tchar * type [] = { "Unknown", "Stopped", // 1 "START_PENDING", // 2 "Stop_pending", // 3 "Running", // 4 "Continue_pending", // 5 "PAUSE_PENDING", // 6 "Paused" // 7 } Return CString (Types [currentState]); } // service_win32, service_driver // service_actate = bit or 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 BYTESNEED, ServicesReturned, ResumeHandle = 0; Rc = :: EnumserviceSstatus (Scman, ServiceType, ServiceState, & Service, Sizeof (Service), & Bytesneeded, & ServicesReturned, & resmehandle); IF ((rc == false) && (: getLastError () == Error_More_Data) { DWORD BYTES = BYTESNEDED SIZEOF (Enum_Service_Status); LPSERVICE = new enum_service_status [bytes]; :: EnumServiceSstatus (Scman, ServiceType, ServiceState, Lpservice, Bytes, & Bytesneeded, & ServicesReturned, & resmehandle); * 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 INFO [NDX] .Service [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; }