#include <windows.h>
#include <cstdio>
#include <vector>
#include <string>
#include <conio.h>
using namespace std;
class ServiceController {
private:
SC_HANDLE hSC;
public:
ServiceController(LPCTSTR MachineName = NULL, DWORD DesiredAccess = SC_MANAGER_ALL_ACCESS){
hSC = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(hSC == NULL){
SCHandleTest(GetLastError());
}
}
~ServiceController(){
CloseServiceHandle(hSC);
}
vector<ENUM_SERVICE_STATUS> EnumServices(DWORD SvcState = SERVICE_STATE_ALL){
vector<ENUM_SERVICE_STATUS> res;
DWORD svcRet, Bytes;
EnumServicesStatus(hSC, SERVICE_DRIVER | SERVICE_WIN32, SvcState, NULL, 0, &Bytes, &svcRet, 0);
ENUM_SERVICE_STATUS *pESS;
pESS = new ENUM_SERVICE_STATUS [Bytes / sizeof(ENUM_SERVICE_STATUS)];
EnumServicesStatus(hSC, SERVICE_DRIVER | SERVICE_WIN32, SvcState, pESS, Bytes, &Bytes, &svcRet, 0);
for(size_t i = 0; i < svcRet; i++){
res.push_back(pESS[i]
;
}
return res;
}
string FmtEnum(ENUM_SERVICE_STATUS ess){
string res = "";
char buff[1024];
/*
SERVICE_FILE_SYSTEM_DRIVER The service is a file system driver.
SERVICE_KERNEL_DRIVER The service is a device driver.
SERVICE_WIN32_OWN_PROCESS The service runs in its own process.
SERVICE_WIN32_SHARE_PROCESS The service shares a process with other services.
If the service type is either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS,
and the service is running in the context of the LocalSystem account,
the following type may also be specified.
SERVICE_INTERACTIVE_PROCESS The service can interact with the desktop.
*/
/*
SERVICE_CONTINUE_PENDING The service continue is pending.
SERVICE_PAUSE_PENDING The service pause is pending.
SERVICE_PAUSED The service is paused.
SERVICE_RUNNING The service is running.
SERVICE_START_PENDING The service is starting.
SERVICE_STOP_PENDING The service is stopping.
SERVICE_STOPPED The service is not running.
*/
/*
SERVICE_ACCEPT_NETBINDCHANGE The service is a network component that can accept changes in its binding without being stopped and restarted.
This control code allows the service to receive SERVICE_CONTROL_NETBINDADD, SERVICE_CONTROL_NETBINDREMOVE, SERVICE_CONTROL_NETBINDENABLE, and SERVICE_CONTROL_NETBINDDISABLE notifications.
Windows NT: This value is not supported.
SERVICE_ACCEPT_PARAMCHANGE The service can reread its startup parameters without being stopped and restarted.
This control code allows the service to receive SERVICE_CONTROL_PARAMCHANGE notifications.
Windows NT: This value is not supported.
SERVICE_ACCEPT_PAUSE_CONTINUE The service can be paused and continued.
This control code allows the service to receive SERVICE_CONTROL_PAUSE and SERVICE_CONTROL_CONTINUE notifications.
SERVICE_ACCEPT_SHUTDOWN The service is notified when system shutdown occurs.
This control code allows the service to receive SERVICE_CONTROL_SHUTDOWN notifications. Note that ControlService cannot send this notification; only the system can send it.
SERVICE_ACCEPT_STOP The service can be stopped.
This control code allows the service to receive SERVICE_CONTROL_STOP notifications.
This value can also contain the following extended control codes, which are supported only by HandlerEx.
Control code Meaning
SERVICE_ACCEPT_HARDWAREPROFILECHANGE The service is notified when the computer
's hardware profile has changed. This enables the system to send SERVICE_CONTROL_HARDWAREPROFILECHANGE notifications to the service.
Windows NT: This value is not supported.
SERVICE_ACCEPT_POWEREVENT The service is notified when the computer
's power status has changed. This enables the system to send SERVICE_CONTROL_POWEREVENT notifications to the service.
Windows NT: This value is not supported.
SERVICE_ACCEPT_SESSIONCHANGE The service is notified when the computer
's session status has changed. This enables the system to send SERVICE_CONTROL_SESSIONCHANGE notifications to the service.
Windows 2000/NT: This value is not supported.
*/
sprintf(buff, "[%s] [%s] SvcType: %d; CurrState: %d; CtrlsAccepted: %d; WaitHint: %d ms",
ess.lpDisplayName, ess.lpServiceName,
ess.ServiceStatus.dwServiceType, ess.ServiceStatus.dwCurrentState,
ess.ServiceStatus.dwControlsAccepted, ess.ServiceStatus.dwWaitHint);
res.append(buff);
return res;
}
private:
void SCHandleTest(long retCode){
if(retCode == ERROR_ACCESS_DENIED){
throw "[ServiceController::OpenSCManager] Доступ запрещен";
} else if(retCode == ERROR_DATABASE_DOES_NOT_EXIST){
throw "[ServiceController::OpenSCManager] Запрошенная база данных не существует";
} else if(retCode == ERROR_INVALID_PARAMETER){
throw "[ServiceController::OpenSCManager] Неверно указаны параметры";
} else{
throw "[ServiceController::OpenSCManager] Неизвестная ошибка";
}
}
};
int main(){
ServiceController sc;
vector<ENUM_SERVICE_STATUS> res = sc.EnumServices();
for(size_t i = 0; i < res.size(); i++){
printf("%s\n", (sc.FmtEnum(res[i]
).c_str());
}
getch();
return 0;
}