服务是一种在操作系统启动的时候就会启动的进程。在操作系统启动时会有两种程序随着系统启动,一种是普通的Win32程序,另一种则是驱动程序。正是基于服务的这种特性,恶意程序往往也会将自身伪装成正常的服务来实现自启动。因此在反病毒的过程中,还是很有必要对服务项进行查看并管理的。
服务管理器的开发原理与之前所讨论的注册表管理器和进程管理器是类似的,主要也是枚举服务并将其显示在“List Control”控件中。而对于服务的管理,是通过服务相关的API函数来实现的。有了本系列之前几篇文章的铺垫,那么我在此就不会对MFC进行过细的讲解。大家可以参考之前的文章进行回顾。
利用MFC创建一个基于对话框的程序,这里需要一个“List Control”、两个“Radio Button”和三个“Button”控件:
图1 程序界面
然后设置“List Control”的控件属性,在“Sytles”中的“View”中,选择“Report”,再选中“Single Selection”选项。然后为其添加一个名为“m_ServiceList”的变量,然后通过编程进行初始化:
void CServiceManageDlg::InitServiceList() { //设置“List Control”控件的扩展风格 m_ServiceList.SetExtendedStyle( m_ServiceList.GetExtendedStyle() | LVS_EX_GRIDLINES //有网络格 | LVS_EX_FULLROWSELECT ); //选中某行使整行高亮(只适用于report风格) //添加列目 m_ServiceList.InsertColumn(0, "序号"); m_ServiceList.InsertColumn(1, "服务名"); m_ServiceList.InsertColumn(2, "显示名"); m_ServiceList.InsertColumn(3, "状态"); //设置列的宽度 m_ServiceList.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER); m_ServiceList.SetColumnWidth(1, 100); m_ServiceList.SetColumnWidth(2, 250); m_ServiceList.SetColumnWidth(3, LVSCW_AUTOSIZE_USEHEADER); }
void CServiceManageDlg::ShowServiceList(DWORD dwServiceType) { m_ServiceList.DeleteAllItems(); //打开服务管理器 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( NULL == hSCM ) { AfxMessageBox("无法打开服务管理器!"); return ; } DWORD dwBufSize = 512 * sizeof(ENUM_SERVICE_STATUS); DWORD dwByteNeeded, dwServicesReturned, lpResumeHandle = 0; ENUM_SERVICE_STATUS SerStatus[512] = { 0 }; //服务项的枚举 BOOL bRet = EnumServicesStatus(hSCM, dwServiceType, SERVICE_STATE_ALL, SerStatus, dwBufSize, &dwByteNeeded, &lpResumeHandle); if ( FALSE == bRet ) { AfxMessageBox("服务项枚举失败!"); CloseServiceHandle(hSCM); return ; } //在列表中显示枚举出来的服务项 for ( DWORD i = 0; i < dwServicesReturned; i ++ ) { CString str; str.Format("%d", i); m_ServiceList.InsertItem(i, str); m_ServiceList.SetItemText(i, 1, SerStatus[i].lpServiceName); m_ServiceList.SetItemText(i, 2, SerStatus[i].lpDisplayName); switch ( SerStatus[i].ServiceStatus.dwCurrentState ) { case SERVICE_PAUSED: { m_ServiceList.SetItemText(i, 3, "暂停"); break; } case SERVICE_STOPPED: { m_ServiceList.SetItemText(i, 3, "停止"); break; } case SERVICE_RUNNING: { m_ServiceList.SetItemText(i, 3, "运行"); break; } default: { m_ServiceList.SetItemText(i, 3, "其他"); } } } CloseServiceHandle(hSCM); }这里要添加头文件“Winsvc.h”。需要特别说明的是,如果想在程序启动时就枚举出Win32服务应用程序,那么就需要在OnInitDialog()中添加:
// TODO: Add extra initialization here InitServiceList(); ShowServiceList(SERVICE_WIN32);
同理,如果想默认显示驱动程序,则将ShowServiceList()函数的参数改写为SERVICE_DRIVER,若什么都不想显示,则在初始化语句中删除这个函数。
void CServiceManageDlg::OnRadioWin32() { // TODO: Add your control notification handler code here ShowServiceList(SERVICE_WIN32); } void CServiceManageDlg::OnRadioDriver() { // TODO: Add your control notification handler code here ShowServiceList(SERVICE_DRIVER); }
根据不同的参数,就能够枚举相应的服务。
</pre><p><span style="font-size:14px;"></span><pre name="code" class="cpp">void CManageServiceDlg::OnBtnStart() { // TODO: Add your control notification handler code here // 选中服务的的索引 POSITION Pos = m_ServiceList.GetFirstSelectedItemPosition(); int nSelect = -1; while ( Pos ) { nSelect = m_ServiceList.GetNextSelectedItem(Pos); } if ( -1 == nSelect ) { AfxMessageBox("请选择要启动的服务"); return ; } // 获取选中服务的服务名 char szServiceName[MAXBYTE] = { 0 }; m_ServiceList.GetItemText(nSelect, 1, szServiceName, MAXBYTE); SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( NULL == hSCM ) { AfxMessageBox("OpenSCManager Error"); return ; } SC_HANDLE hSCService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS); // 启动服务 BOOL bRet = StartService(hSCService, 0, NULL); if ( bRet == TRUE ) { m_ServiceList.SetItemText(nSelect, 3, "运行"); } else { int n = GetLastError(); } CloseServiceHandle(hSCService); CloseServiceHandle(hSCM); } void CManageServiceDlg::OnBtnStop() { // TODO: Add your control notification handler code here // 选中服务的的索引 POSITION Pos = m_ServiceList.GetFirstSelectedItemPosition(); int nSelect = -1; while ( Pos ) { nSelect = m_ServiceList.GetNextSelectedItem(Pos); } if ( -1 == nSelect ) { AfxMessageBox("请选择要停止的服务"); return ; } // 获取选中服务的服务名 char szServiceName[MAXBYTE] = { 0 }; m_ServiceList.GetItemText(nSelect, 1, szServiceName, MAXBYTE); SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( NULL == hSCM ) { AfxMessageBox("OpenSCManager Error"); return ; } SC_HANDLE hSCService = OpenService(hSCM, szServiceName, SERVICE_ALL_ACCESS); SERVICE_STATUS ServiceStatus; // 停止服务 BOOL bRet = ControlService(hSCService, SERVICE_CONTROL_STOP, &ServiceStatus); if ( bRet == TRUE ) { m_ServiceList.SetItemText(nSelect, 3, "停止"); } else { int n = GetLastError(); } CloseServiceHandle(hSCService); CloseServiceHandle(hSCM); }
图2 运行程序
程序启动时就已经列出了本机所有的Win32服务应用程序,通过单选按钮就可以切换到驱动程序的显示,这里也可以用专业软件SREng对比一下:
二者是一致的,说明我们的程序没有问题。
原文地址:http://blog.csdn.net/ioio_jy/article/details/40048477