📄 05o008.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title></title>
<link rel="stylesheet" type="text/css" href="../../vckbase.css">
</head>
<body>
<div align="justify">
<table border="0" width="100%" class="font" height="57">
<tr>
<td width="27%" height="6" class="bigfont" bgcolor="#B8CFE7" align="center" bordercolor="#800080">
<font color="#800080">VC知识库(五)</font>
</td>
<td width="73%" height="6" class="bigfont" bgcolor="#B8CFE7" align="center" bordercolor="#800080">
<font color="#800080">www.vckbase.com</font>
</td>
</tr>
<tr>
<td width="100%" height="4" class="header" valign="top" align="center" colspan="2">
<hr>
</td>
</tr>
<tr>
<td width="100%" height="17" class="header" valign="top" align="center" colspan="2">
<font color="#000000"><strong>Enumerate NT services </strong></font>
</td>
</tr>
<tr>
<td width="100%" height="17" class="info" align="center" colspan="2">
<font color="#000000"><strong>闻怡洋译</strong></font>
</td>
</tr>
<tr>
<td width="100%" height="22" class="font" colspan="2">
<hr>
</td>
</tr>
<tr>
<td width="100%" height="5" class="font" colspan="2">
<!-- Author and contact details -->
<p><small>by <a href="mailto:ScaAdmin@ScaSoftware.com">Zoran M.Todorovic</a>. </small></p>
<p>下面的文章提供了访问NT中所有Service的功能,每次列举Services时,函数会返回一个列表。
列表的内容依赖于你所使用的参数。 (我认为这是一种很巧妙的编程方法,它极大的减轻了数据和函数的冗余,利用一个<font
color="#008040"><strong>STATIC函数来产生本身对象的列表或者是来产生对象</strong></font>)</p>
<p>Class declaration:声明</p>
<tt><font color="#990000">
<p><font color="#0000ff"><font size="2">class</font></font> <font size="2"> TTrixServiceInfo {<br>
<font color="#0000ff">public</font>:<br>
CString ServiceName;<br>
CString DisplayName;<br>
CString BinaryPath;<br>
DWORD ServiceType;<br>
DWORD StartType;<br>
DWORD ErrorControl;<br>
DWORD CurrentState;<br>
<font color="#0000ff">public</font>:<br>
TTrixServiceInfo();<br>
TTrixServiceInfo& <font color="#0000ff">operator</font>=(<font
color="#0000ff">const</font> TTrixServiceInfo& source);<br>
CString GetServiceType(<font color="#0000ff">void</font>);<br>
CString GetStartType(<font color="#0000ff">void</font>);<br>
CString GetErrorControl(<font color="#0000ff">void</font>);<br>
CString GetCurrentState(<font color="#0000ff">void</font>);<br>
<font color="#0000ff">static</font> TTrixServiceInfo
*EnumServices(DWORD serviceType,<br>
DWORD serviceState,DWORD *count);<br>
};<br>
</font></font></tt><strong>Description:</strong>类的每一个实例都包含了SERVICE的各种信息,如果想得到SERVICE的列表,请调用<tt><font
color="#990000">TTrixServiceInfo::EnumServices</font></tt>(...)。<big><br>
</big><br>
<small>参数ServiceType的取值可能是:</small>SERVICE_WIN32 and SERVICE_DRIVER.</p>
<p><small>参数ServiceState的取值可能是:SERVICE_ACTIVE and SERVICE_INACTIVE.</small></p>
<p>EnumServices(...)将返回<big><strong>TTrixServiceInfo</strong></big>对象的列表,(如果出错返回NULL)。列表中对象的个数可以通过参数返回时得到。</p>
<p>下面是具体的代码:</p>
<tt><font color="#990000">
<pre><font size="2">TTrixServiceInfo *lpservice = NULL;
DWORD count;
lpservice = TTrixServiceInfo::EnumServices(SERVICE_WIN32,SERVICE_ACTIVE|SERVICE_INACTIVE,<u>&count</u></font></font><font
color="#000080">/*得到个数*</font><font color="#990000"><font size="2">/);
<font color="#0000ff">if</font> (lpservice) {//如果正确
<font
color="#0000ff">for</font> (DWORD index = 0; index < count; index ++) {
printf("%d. %s, %s\n", index, lpservice[index].DisplayName,
lpservice[index].GetCurrentState());
}
<font
color="#0000ff">delete</font> [] lpservice;
}</font><small>
</small></font></tt></pre>
<p><strong><small>Source code:</small></strong></p>
<tt><font color="#990000">
<pre><font size="2">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;
}</font></font></tt></pre>
</td>
</tr>
<tr>
<td width="100%" height="12" class="font" colspan="2">
</td>
</tr>
<tr>
<td width="100%" height="6" class="font" colspan="2">
</td>
</tr>
<tr>
<td width="100%" height="8" class="font" colspan="2">
</td>
</tr>
<tr>
<td width="100%" height="17" class="font" colspan="2"></td>
</tr>
</table>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -