突然想仿照XueTr中的服务管理写个小程序。
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
打开服务管理器,SC_MANAGER_ALL_ACCESS的权限有点大,懒得查了。
EnumServicesStatusEx枚举服务,也可以获得Driver的服务,需要注意的是这个函数的缓冲区是不固定的,贸然使用一个过大或者过小的缓冲都是不明智的。
EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (PBYTE)pPssp, 0, &dwNeed, &dwRet, NULL, NULL);
if (dwNeed == 0) return;
pPssp = (LPENUM_SERVICE_STATUS_PROCESS)malloc(dwNeed);
ZeroMemory(pPssp, dwNeed);
if (!EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (PBYTE)pPssp, dwNeed, &dwNeed, &dwRet, NULL, NULL))
{
free(pPssp);
return;
}
还有,dwRet里放的是ENUM_SERVICE_STATUS_PROCESS数组的元素个数,并不是字节数。
for (DWORD i = 0; i < dwRet; i++)
{
//do some thing
}
可以通过pPssp[i]取得一些信息:服务名称,显示名称,目前状态等。
不过获取的信息还是有限,但是拿到了服务名称,进而可以继续操作。
hSrv = OpenService(hSCM, pPssp[i].lpServiceName, SERVICE_QUERY_CONFIG);
利用QueryServiceConfig可以查询到服务的启动方式,文件路径等。
QueryServiceConfig(hSrv, pQsc, 0, &dwNeed);
if (dwNeed > 0)
{
pQsc = (LPQUERY_SERVICE_CONFIG)malloc(dwNeed);
ZeroMemory(pQsc, dwNeed);
if (QueryServiceConfig(hSrv, pQsc, dwNeed, &dwNeed))
{
//do some thing
}
free(pQsc);
}
利用QueryServiceConfig2可以查询到服务的描述信息。(看清楚,后面有个数字"2")
QueryServiceConfig2(hSrv, SERVICE_CONFIG_DESCRIPTION, (PBYTE)pSd, 0, &dwNeed);
if (dwNeed > 0)
{
pSd = (LPSERVICE_DESCRIPTION)malloc(dwNeed);
ZeroMemory(pSd, dwNeed);
if (QueryServiceConfig2(hSrv, SERVICE_CONFIG_DESCRIPTION, (PBYTE)pSd, dwNeed, &dwNeed))
{
//do some thing
}
free(pSd);
}
------------
好了,到此为止已经得到了:
服务名称
显示名称
目前状态
启动方式
文件路径(如果是svchost方式启动还要继续获取DLL路径)
服务描述
有了这些信息,后面可以做很多事情了。