服务控制程序
2011-04-25 17:00
260 查看
Win服务控制程序--serConf.exe
前几天写一个windows服务管理程序,由于要做驱动开发了,但是对驱动程序进行安装加载测试时,大部分都使用服务的形式来启动它。
于是,自己就从网上下了几个安装驱动的服务控制程序,但是它们只提供简单的驱动路径进行安装,其他的服务名和服务描述等都被默认设置了,而且要手工写入程序路径。如果要停止和卸载程序时,并没有提供系统SCM管理库中的服务枚举,只是硬性的操作自己刚才安装的驱动程序。
以上驱动服务管理程序都很好,嘿嘿~~~~,只是有点不符合自己的应用要求而已。如果我想安装应用程序和服务程序就不知所措了。(^ &^)
所以,自己就做了一个服务控制程序,可以实现【应用程序】,【驱动程序】和【服务程序】安装成系统服务的方式来启动。
一.安装服务
本人给程序付了个标题(serConf.exe),见笑了~~~
1.1.安装【应用程序】:由于本人的目的不在于应用程序安装上,所以在写该程序时,就把它给带上了。这种启动方式很简单,主要是在注册表的子键【Run】写启动应用程序。
如果,想把PE应用程序当做服务启动的话,可以写一个带有ServiceMain入口点的服务程序,在该服务程序中创建一个进程来启动要加载的PE应用程序。具体的启动方式自己可以设定。
1.2.安装【驱动程序】:SCM数据库的控制函数可以实现安装,启动,停止和卸载相应的服务程序。驱动程序也是这样,该选项启动的驱动只指定SERVICE_KERNEL_DRIVER类型的驱动,在测试的时候,可以启动成功。如果要启动其他类型的驱动程序,例如:文件系统驱动程序等。自己可以测试一下,应该可以安装成功和启动成功等。
1.3.安装【服务程序】:该选项要启动的程序是标准的符合系统服务要求的服务程序,必须要有ServiceMain入口点函数,如果想启动这样的服务,可以自己写一个服务程序来测试一下,可以成功!该选项与【驱动程序】的选项在参数设置的时候有点改变,所以可以启动不同类型的程序。这点请参考【MSDN】服务类型。
二.管理服务
这一功能模块是用来管理系统现有的服务程序。
它主要列举服务的7个属性来表示服务的。
【服务名称】:指定了SCM数据库中服务的唯一标识符,可以在创建服务的时候指定。
【服务类型】:表示该服务的类型,主要有驱动服务,文件系统驱动,独立进程和共享进程,当然还有一些无法识别的服务类型。
【运行状态】:指服务程序的当前状态,除了大家常见的正在运行,已经停止等运行状态外,该程序还描述了一些其他的运行状态,将要运行,将要停止等...
【启动时期】:指出服务程序是如何启动的,主要有boot启动,servicestart启动,IOinitSystem启动,System启动等,还有其他的启动方式,就标志为【无效启动】了。
【服务描述】:这个就不用多说了,主要指对服务程序的具体描述信息。这个在安装服务时,可以指定。
【运行账户】:在系统中,运行该服务的账户信息。windows系统为了保证服务程序不能被黑客利用漏洞进行权限提升,就规定了三个服务运行账户:localsystem,networkservice和localservice。
【程序路径】:指定了列举的服务程序所在的路径,其中也包括运行的参数。它可以在安装服务程序的时候,点击【浏览】选择安装的程序路径。
其实,在SCM库的很多服务之间存在着依赖关系,对于服务之间的依赖就没写;能够枚举出来的话,能够对某一服务有一个更深的了解。具体请参考【MSDN】服务API。
2.1.【启动服务】:对某一选定的,处于停止状态的服务进行重新启动。可能在启动某一服务的时候,无法成功启动,有些许原因,该程序已经给出,可以自己测试一下。
2.2.【停止服务】:主要对正在运行的服务程序进行停止操作,在停止某一指定服务程序时,也会碰到停止失败的问题,可能由于权限,或正在运行等原因,程序已给出。
2.3.【卸载服务】:对已经安装的服务进行卸载,在卸载前,必须保证服务程序处于停止状态,自己可以切换操作。
写了不少文字,有点累啊,嘿嘿~~~~~~
程序未处理的问题:
1. 【安装模块】已经成功安装的服务程序没法在【管理模块】中直接浏览,本人并没有写这方面的代码来实现,必须重启该程序来查看。如果觉得不方便,可以自己添加代码,实现进程间共享内存的方式来实现,看个人实现方式的爱好喽(* ¥*)~6……~
2.该程序没有在安装服务模块中,提供服务的启动方式选项,默认指定方式是StartService启动,如果要是做木马测试的话,可以设置具体的随机启动方式。
三.【操作方法】:
具体的操作也不用啰嗦,不大的一个程序很简单。主要在【管理服务】的时候,必须双击列表框的第一列,使得checkbox被同时选中才能进行操作,而且对其操作进行限制,操作必须符合指定要求才能进行,有点繁琐啊,呜呜,我也是为了使得每一步操作进行严格控制,防止误操作带来不必要的麻烦,(*^__^*) 嘻嘻……
四.其他帮助
serConf.exe通过枚举系统服务,也可以来手工查找以服务形式启动的木马程序,只要木马程序没有对服务枚举API进行hook和对native API进行hook挂钩进行隐藏启动方式,就可以将其枚举出来,查看路径;直接停止,卸载木马服务程序。
本人对2007僵尸王(僵尸网络)的源代码进行过分析,其启动方式就是自己写服务程序,以服务方式来启动。利用该程序可以对其进行枚举查杀。
五.部分源代码
5.1.Enumserv类
//枚举系统服务--------------------------------------------------------
BOOL CEnumserv::EnumService()//default pParam is 1;
{
LPENUM_SERVICE_STATUS sc_status;//定义服务状态结构,可通过MSDN查询
DWORD configSize=0;
DWORD size=0;//设置sc_status大小
DWORD ret=0;
BOOL flag;//判断枚举系统服务是否成功
sc_status=(LPENUM_SERVICE_STATUS)::LocalAlloc(LPTR,64*MAX_NUM);
flag=::EnumServicesStatus(sc_handle,SERVICE_WIN32|SERVICE_DRIVER,SERVICE_STATE_ALL, sc_status,MAX_NUM*64,&size,&ret,NULL);//枚举系统服务
if(!flag)//枚举失败
{
::MessageBox(this->m_hWnd,"枚举服务失败","警告",MB_OK||MB_ICONERROR);
::LocalFree(sc_status);//销毁分配内存--
return FALSE;//结束函数
}
else //枚举成功
{
::_ultoa(ret,serviceNum,10);
for(int i=0;i<ret;i++)//遍历ENUM_SERVICE_STATUS结构数组
{
this->m_enumlist.InsertItem(i,sc_status[i].lpServiceName);//插入第一行第一列数据为服务名
////-----------------------------------
LPTSTR sendType=NULL;
sendType=ser_status.EnumStatus(i,TRUE,sc_status);
this->m_enumlist.SetItemText(i,1,sendType);
//-----------------------------------------
//------------------------------
LPTSTR cStatus=NULL;
cStatus=ser_status.EnumStatus(i,FALSE,sc_status);
this->m_enumlist.SetItemText(i,2,cStatus);
//-------------------------------------
LPTSTR startString=NULL;
startString=ser_status.serConfig(sc_handle,i,1,sc_status);
this->m_enumlist.SetItemText(i,3,startString);
//-------------------------------------
LPTSTR displayname=NULL;
displayname=ser_status.serConfig(sc_handle,i,2,sc_status);
this->m_enumlist.SetItemText(i,4,displayname);
//---------------------------------------
LPTSTR runacount=NULL;
runacount=ser_status.serConfig(sc_handle,i,3,sc_status);
this->m_enumlist.SetItemText(i,5,runacount);
//---------------------------------------
LPTSTR pathname=NULL;
pathname=ser_status.serConfig(sc_handle,i,4,sc_status);
this->m_enumlist.SetItemText(i,6,pathname);
//------------------------------------
}//结束FOR循环
flag=TRUE;
::WaitForSingleObject(sc_handle,INFINITE);
::LocalFree(sc_status);//销毁分配内存--
return flag;
}
}
5.2.serStatus类
//获取服务类型--------------------------------------------------------
LPTSTR SerStatus::EnumStatus(int index,BOOL flag,LPENUM_SERVICE_STATUS status)
{
int sIndex=index;
LPENUM_SERVICE_STATUS scm_status=status;
LPTSTR resultType=NULL;
LPTSTR resultStatus=NULL;
if(flag)
{
DWORD serviceType=0;
serviceType=scm_status[sIndex].ServiceStatus.dwServiceType;
switch(serviceType)
{
case SERVICE_FILE_SYSTEM_DRIVER:
resultType="文件系统驱动";
break;
case SERVICE_KERNEL_DRIVER:
resultType="驱动服务";
break;
case SERVICE_WIN32_OWN_PROCESS:
resultType="独立进程";
break;
case SERVICE_WIN32_SHARE_PROCESS:
resultType="共享进程";
break;
case SERVICE_ADAPTER:
resultType="Adapter驱动";
break;
case SERVICE_RECOGNIZER_DRIVER:
resultType="Recognizer驱动";
break;
default:
resultType="无法识别";
break;
}
return resultType;
}
else
{
DWORD currentStatus=0;
currentStatus=scm_status[sIndex].ServiceStatus.dwCurrentState;
switch(currentStatus)
{
case SERVICE_RUNNING:
resultStatus="正在运行";
break;
case SERVICE_START_PENDING:
resultStatus="准备启动";
break;
case SERVICE_STOP_PENDING:
resultStatus="准备停止";
break;
case SERVICE_STOPPED:
resultStatus="已经停止";
break;
default:
resultStatus=NULL;
break;
}
return resultStatus;
}
}
//获取服务启动类型--------------------------------------------------------
LPTSTR SerStatus::serConfig(SC_HANDLE scm,int index,int flag,LPENUM_SERVICE_STATUS status)
{
SC_HANDLE scmHander=scm;
int sIndex=index;
BOOL resultFlag=TRUE;
DWORD needbyte=0;
DWORD size;
DWORD error=0;
DWORD starttype=0;
LPTSTR pathname=NULL;
LPTSTR resultString=NULL;
LPQUERY_SERVICE_CONFIG Serconfig;
LPENUM_SERVICE_STATUS scm_status=status;
LPTSTR serviceName=scm_status[sIndex].lpServiceName;
SC_HANDLE sc_h=OpenService(scmHander, serviceName,SERVICE_QUERY_CONFIG);
if (sc_h == NULL)
{
return NULL;
}
if( !QueryServiceConfig(
sc_h,
NULL,
0,
&needbyte))
{
error = GetLastError();
if(error==ERROR_INSUFFICIENT_BUFFER)
{
size=needbyte;
Serconfig=(LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, size);
}
else
{
::CloseServiceHandle(sc_h);
return NULL;
}
}
if( !QueryServiceConfig(
sc_h,
Serconfig,
size,
&needbyte) )
{
::CloseServiceHandle(sc_h);
return NULL;
}
else
{
switch(flag)
{
case SERVICE_STARTTYPE:
starttype=Serconfig->dwStartType;
switch(starttype)
{
case SERVICE_AUTO_START:
resultString="(System)启动";
break;
case SERVICE_BOOT_START:
resultString="(Boot)引导";
break;
case SERVICE_DEMAND_START:
resultString="(startservice)启动";
break;
case SERVICE_SYSTEM_START:
resultString="(IoInitSystem)启动";
break;
case SERVICE_DISABLED:
resultString="无效启动";
break;
default:
resultString="无效服务";
break;
}
break;
case SERVICE_DISC:
resultString=Serconfig->lpDisplayName;
break;
case SERVICE_ACOUNT:
resultString=Serconfig->lpServiceStartName;
break;
case SERVICE_PATH:
resultString=Serconfig->lpBinaryPathName;
break;
default:
return NULL;
}
::LocalFree(Serconfig);
}
return resultString;
}
5.3.heckSerStatus类
//确认服务状态--------------------------------------------------------
int CheckSerStatus::checkStatus(LPTSTR serviceName)
{
int resultFlag=0;
BOOL checkFlag=FALSE;
DWORD currentState=0;
LPSERVICE_STATUS serviceStatus=(LPSERVICE_STATUS)::LocalAlloc(LPTR,28*8);//
sc_open=::OpenService(sc_scm,serviceName,SERVICE_QUERY_STATUS);
if(sc_open!=NULL)
{
checkFlag=::QueryServiceStatus(sc_open,serviceStatus);
if(checkFlag!=TRUE)
{
::LocalFree(serviceStatus);//销毁分配内存--
return 5;
}
else
{
currentState=serviceStatus->dwCurrentState;
switch(currentState)
{
case SERVICE_RUNNING:
resultFlag=1;
break;
case SERVICE_START_PENDING:
resultFlag=2;
break;
case SERVICE_STOP_PENDING:
resultFlag=3;
break;
case SERVICE_STOPPED:
resultFlag=4;
break;
default:
break;
}
::CloseServiceHandle(sc_open);
}
}
else
{
::LocalFree(serviceStatus);//销毁分配内存--
::CloseServiceHandle(sc_open);//销毁句柄--
return 5;
}
::LocalFree(serviceStatus);//销毁分配内存--
::CloseServiceHandle(sc_open);//销毁句柄--
return resultFlag;
}
5.4.Addserv类
//创建驱动服务--------------------------------------------------------
BOOL InstallService::CreateQServ(LPTSTR serviceName,LPTSTR displayName,LPTSTR pathName)
{
BOOL result_scm;
result_scm=this->checkSCM();
if(!result_scm)
{
::MessageBox(NULL,"SCM打开失败,\n无法安装应用程序服务!","警告",MB_OK|MB_ICONERROR);
return result_scm;
}
else
{
SC_HANDLE sc_createEx=::CreateService(sc_scm,serviceName,displayName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,pathName,NULL,NULL,NULL,NULL,NULL);
int error;
if(sc_createEx==NULL)
{
error=::GetLastError();
if(error==ERROR_DUPLICATE_SERVICE_NAME)
{
::MessageBox(NULL,"创建失败提示:\n服务描述重名,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
if(error==ERROR_INVALID_NAME)
{
::MessageBox(NULL,"创建失败提示:\n服务名无效,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
if(error==ERROR_INVALID_SERVICE_ACCOUNT)
{
::MessageBox(NULL,"创建失败提示:\n创建者账户不存在,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
if(error==ERROR_SERVICE_EXISTS||error==ERROR_SERVICE_MARKED_FOR_DELETE)
{
::MessageBox(NULL,"创建失败提示:\n该服务已经创建,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
}
else
{
this->sc_create=sc_createEx;
::Sleep(50);
::MessageBox(NULL,"创建成功提示:\n该服务创建成功!","提示",MB_OK|MB_ICONWARNING);
::CloseServiceHandle(sc_createEx);//销毁句柄--
::CloseServiceHandle(this->sc_create);
return TRUE;
}
}
}
//启动服务函数--------------------------------------------------------
BOOL InstallService::StartService(LPTSTR serviceName)
{
BOOL result_scm;
CString showInfo=_T("");
BOOL result;
LPSERVICE_STATUS serStatus=(LPSERVICE_STATUS)::LocalAlloc(LPTR,28*8);
result_scm=this->checkSCM();
if(!result_scm)
{
::MessageBox(NULL,"SCM打开失败,\n无法安装应用程序服务!","警告",MB_OK|MB_ICONERROR);
return result_scm;
}
else
{
SC_HANDLE sService =OpenService(sc_scm,serviceName,SERVICE_ALL_ACCESS);
if (sService != NULL)
{
showInfo="是否启动服务:\n【";
showInfo+=serviceName;
showInfo+="】";
if(IDYES==::MessageBox(NULL,showInfo,"询问",MB_YESNO|MB_ICONQUESTION))
{
//--------------------
if(::QueryServiceStatus(sService,serStatus))
{
if(serStatus->dwServiceType==SERVICE_KERNEL_DRIVER||serStatus->dwServiceType==SERVICE_FILE_SYSTEM_DRIVER||serStatus->dwServiceType==SERVICE_RECOGNIZER_DRIVER)
result=::StartService(sService,NULL,NULL);
else
result=::StartService(sService,0,NULL);
}
//--------------------------
if(result==TRUE)
{
if(serStatus->dwCurrentState=SERVICE_START_PENDING||serStatus->dwCurrentState==SERVICE_RUNNING)
{
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】启动成功!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return result;
}
else
{
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】启动失败!";
::MessageBox(NULL,showInfo,"警告",MB_OK|MB_ICONERROR);
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
//-----------------
else
{
int error=::GetLastError();
switch(error)
{
case ERROR_ACCESS_DENIED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】启动权限不够!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_PATH_NOT_FOUND:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】加载路径不存在!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DATABASE_LOCKED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】加载的SCM锁定!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_DELETED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】依赖的服务不存在或已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_FAIL:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】依赖的服务启动失败!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DISABLED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】不可用!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_MARKED_FOR_DELETE:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_REQUEST_TIMEOUT:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】已启动,正在注册!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
}
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
//----------------------------------
else
{
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
else
{
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
}
//启动服务--------------------------------------------------------
void CEnumserv::OnStartservice()
{
// TODO: Add your control notification handler code here
//--------------------------------
CString itemName;
CString showInfo=_T("");
BOOL result;
char item_name[MAX_PATH-100];
LPSERVICE_STATUS serStatus=(LPSERVICE_STATUS)::LocalAlloc(LPTR,28*8);
this->m_enumlist.GetItemText(this->m_itemIndex,0,item_name,MAX_PATH-100);
itemName=item_name;
if(this->m_sName!=itemName)
{
showInfo="请双击第一列选中";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
::LocalFree(serStatus);
return;
}
else
{
if(!this->m_enumlist.GetCheck(this->m_itemIndex))
{
showInfo="请选中【";
showInfo+=m_sName;
showInfo+="】列的CheckBox框!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
::LocalFree(serStatus);
return;
}
else
{
//-------------------------------
if(sc_handle==NULL)
{
::LocalFree(serStatus);//销毁分配内存--
return;
}
else
{
SC_HANDLE sService =OpenService(sc_handle,m_sName,SERVICE_ALL_ACCESS);
if (sService != NULL)
{
showInfo="是否启动服务:\n【";
showInfo+=this->m_sName;
showInfo+="】";
if(IDYES==::MessageBox(NULL,showInfo,"询问",MB_YESNO|MB_ICONQUESTION))
{
if(::QueryServiceStatus(sService,serStatus))
{
if(serStatus->dwServiceType==SERVICE_KERNEL_DRIVER||serStatus->dwServiceType==SERVICE_FILE_SYSTEM_DRIVER||serStatus->dwServiceType==SERVICE_RECOGNIZER_DRIVER)
result=StartService(sService,NULL,NULL);
else
result=StartService(sService,0,NULL);
}
//-------------------
if(result==TRUE)
{
if(serStatus->dwCurrentState=SERVICE_START_PENDING||serStatus->dwCurrentState==SERVICE_RUNNING)
{
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】启动成功!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
this->m_enumlist.SetItemText(this->m_itemIndex,2,"正在启动");
::LocalFree(serStatus);//--
return;
}
else
{
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】启动失败!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
::LocalFree(serStatus);//--
return;
}
}
else
{
int error=::GetLastError();
switch(error)
{
case ERROR_ACCESS_DENIED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】启动权限不够!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_PATH_NOT_FOUND:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】加载路径不存在!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DATABASE_LOCKED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】加载的SCM锁定!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_DELETED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】依赖的服务不存在或已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_FAIL:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】依赖的服务启动失败!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DISABLED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】不可用!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_MARKED_FOR_DELETE:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_REQUEST_TIMEOUT:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】已启动,正在注册!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
}
::LocalFree(serStatus);//--
}
//-----------------
}
else
{
::LocalFree(serStatus);//--
return;
}
::CloseServiceHandle(sService);//销毁句柄--
}
}
}
}
}
//结束(*^__^*)---【源码下载】:http://127.0.0.1/serConf.exe
前几天写一个windows服务管理程序,由于要做驱动开发了,但是对驱动程序进行安装加载测试时,大部分都使用服务的形式来启动它。
于是,自己就从网上下了几个安装驱动的服务控制程序,但是它们只提供简单的驱动路径进行安装,其他的服务名和服务描述等都被默认设置了,而且要手工写入程序路径。如果要停止和卸载程序时,并没有提供系统SCM管理库中的服务枚举,只是硬性的操作自己刚才安装的驱动程序。
以上驱动服务管理程序都很好,嘿嘿~~~~,只是有点不符合自己的应用要求而已。如果我想安装应用程序和服务程序就不知所措了。(^ &^)
所以,自己就做了一个服务控制程序,可以实现【应用程序】,【驱动程序】和【服务程序】安装成系统服务的方式来启动。
一.安装服务
本人给程序付了个标题(serConf.exe),见笑了~~~
1.1.安装【应用程序】:由于本人的目的不在于应用程序安装上,所以在写该程序时,就把它给带上了。这种启动方式很简单,主要是在注册表的子键【Run】写启动应用程序。
如果,想把PE应用程序当做服务启动的话,可以写一个带有ServiceMain入口点的服务程序,在该服务程序中创建一个进程来启动要加载的PE应用程序。具体的启动方式自己可以设定。
1.2.安装【驱动程序】:SCM数据库的控制函数可以实现安装,启动,停止和卸载相应的服务程序。驱动程序也是这样,该选项启动的驱动只指定SERVICE_KERNEL_DRIVER类型的驱动,在测试的时候,可以启动成功。如果要启动其他类型的驱动程序,例如:文件系统驱动程序等。自己可以测试一下,应该可以安装成功和启动成功等。
1.3.安装【服务程序】:该选项要启动的程序是标准的符合系统服务要求的服务程序,必须要有ServiceMain入口点函数,如果想启动这样的服务,可以自己写一个服务程序来测试一下,可以成功!该选项与【驱动程序】的选项在参数设置的时候有点改变,所以可以启动不同类型的程序。这点请参考【MSDN】服务类型。
二.管理服务
这一功能模块是用来管理系统现有的服务程序。
它主要列举服务的7个属性来表示服务的。
【服务名称】:指定了SCM数据库中服务的唯一标识符,可以在创建服务的时候指定。
【服务类型】:表示该服务的类型,主要有驱动服务,文件系统驱动,独立进程和共享进程,当然还有一些无法识别的服务类型。
【运行状态】:指服务程序的当前状态,除了大家常见的正在运行,已经停止等运行状态外,该程序还描述了一些其他的运行状态,将要运行,将要停止等...
【启动时期】:指出服务程序是如何启动的,主要有boot启动,servicestart启动,IOinitSystem启动,System启动等,还有其他的启动方式,就标志为【无效启动】了。
【服务描述】:这个就不用多说了,主要指对服务程序的具体描述信息。这个在安装服务时,可以指定。
【运行账户】:在系统中,运行该服务的账户信息。windows系统为了保证服务程序不能被黑客利用漏洞进行权限提升,就规定了三个服务运行账户:localsystem,networkservice和localservice。
【程序路径】:指定了列举的服务程序所在的路径,其中也包括运行的参数。它可以在安装服务程序的时候,点击【浏览】选择安装的程序路径。
其实,在SCM库的很多服务之间存在着依赖关系,对于服务之间的依赖就没写;能够枚举出来的话,能够对某一服务有一个更深的了解。具体请参考【MSDN】服务API。
2.1.【启动服务】:对某一选定的,处于停止状态的服务进行重新启动。可能在启动某一服务的时候,无法成功启动,有些许原因,该程序已经给出,可以自己测试一下。
2.2.【停止服务】:主要对正在运行的服务程序进行停止操作,在停止某一指定服务程序时,也会碰到停止失败的问题,可能由于权限,或正在运行等原因,程序已给出。
2.3.【卸载服务】:对已经安装的服务进行卸载,在卸载前,必须保证服务程序处于停止状态,自己可以切换操作。
写了不少文字,有点累啊,嘿嘿~~~~~~
程序未处理的问题:
1. 【安装模块】已经成功安装的服务程序没法在【管理模块】中直接浏览,本人并没有写这方面的代码来实现,必须重启该程序来查看。如果觉得不方便,可以自己添加代码,实现进程间共享内存的方式来实现,看个人实现方式的爱好喽(* ¥*)~6……~
2.该程序没有在安装服务模块中,提供服务的启动方式选项,默认指定方式是StartService启动,如果要是做木马测试的话,可以设置具体的随机启动方式。
三.【操作方法】:
具体的操作也不用啰嗦,不大的一个程序很简单。主要在【管理服务】的时候,必须双击列表框的第一列,使得checkbox被同时选中才能进行操作,而且对其操作进行限制,操作必须符合指定要求才能进行,有点繁琐啊,呜呜,我也是为了使得每一步操作进行严格控制,防止误操作带来不必要的麻烦,(*^__^*) 嘻嘻……
四.其他帮助
serConf.exe通过枚举系统服务,也可以来手工查找以服务形式启动的木马程序,只要木马程序没有对服务枚举API进行hook和对native API进行hook挂钩进行隐藏启动方式,就可以将其枚举出来,查看路径;直接停止,卸载木马服务程序。
本人对2007僵尸王(僵尸网络)的源代码进行过分析,其启动方式就是自己写服务程序,以服务方式来启动。利用该程序可以对其进行枚举查杀。
五.部分源代码
5.1.Enumserv类
//枚举系统服务--------------------------------------------------------
BOOL CEnumserv::EnumService()//default pParam is 1;
{
LPENUM_SERVICE_STATUS sc_status;//定义服务状态结构,可通过MSDN查询
DWORD configSize=0;
DWORD size=0;//设置sc_status大小
DWORD ret=0;
BOOL flag;//判断枚举系统服务是否成功
sc_status=(LPENUM_SERVICE_STATUS)::LocalAlloc(LPTR,64*MAX_NUM);
flag=::EnumServicesStatus(sc_handle,SERVICE_WIN32|SERVICE_DRIVER,SERVICE_STATE_ALL, sc_status,MAX_NUM*64,&size,&ret,NULL);//枚举系统服务
if(!flag)//枚举失败
{
::MessageBox(this->m_hWnd,"枚举服务失败","警告",MB_OK||MB_ICONERROR);
::LocalFree(sc_status);//销毁分配内存--
return FALSE;//结束函数
}
else //枚举成功
{
::_ultoa(ret,serviceNum,10);
for(int i=0;i<ret;i++)//遍历ENUM_SERVICE_STATUS结构数组
{
this->m_enumlist.InsertItem(i,sc_status[i].lpServiceName);//插入第一行第一列数据为服务名
////-----------------------------------
LPTSTR sendType=NULL;
sendType=ser_status.EnumStatus(i,TRUE,sc_status);
this->m_enumlist.SetItemText(i,1,sendType);
//-----------------------------------------
//------------------------------
LPTSTR cStatus=NULL;
cStatus=ser_status.EnumStatus(i,FALSE,sc_status);
this->m_enumlist.SetItemText(i,2,cStatus);
//-------------------------------------
LPTSTR startString=NULL;
startString=ser_status.serConfig(sc_handle,i,1,sc_status);
this->m_enumlist.SetItemText(i,3,startString);
//-------------------------------------
LPTSTR displayname=NULL;
displayname=ser_status.serConfig(sc_handle,i,2,sc_status);
this->m_enumlist.SetItemText(i,4,displayname);
//---------------------------------------
LPTSTR runacount=NULL;
runacount=ser_status.serConfig(sc_handle,i,3,sc_status);
this->m_enumlist.SetItemText(i,5,runacount);
//---------------------------------------
LPTSTR pathname=NULL;
pathname=ser_status.serConfig(sc_handle,i,4,sc_status);
this->m_enumlist.SetItemText(i,6,pathname);
//------------------------------------
}//结束FOR循环
flag=TRUE;
::WaitForSingleObject(sc_handle,INFINITE);
::LocalFree(sc_status);//销毁分配内存--
return flag;
}
}
5.2.serStatus类
//获取服务类型--------------------------------------------------------
LPTSTR SerStatus::EnumStatus(int index,BOOL flag,LPENUM_SERVICE_STATUS status)
{
int sIndex=index;
LPENUM_SERVICE_STATUS scm_status=status;
LPTSTR resultType=NULL;
LPTSTR resultStatus=NULL;
if(flag)
{
DWORD serviceType=0;
serviceType=scm_status[sIndex].ServiceStatus.dwServiceType;
switch(serviceType)
{
case SERVICE_FILE_SYSTEM_DRIVER:
resultType="文件系统驱动";
break;
case SERVICE_KERNEL_DRIVER:
resultType="驱动服务";
break;
case SERVICE_WIN32_OWN_PROCESS:
resultType="独立进程";
break;
case SERVICE_WIN32_SHARE_PROCESS:
resultType="共享进程";
break;
case SERVICE_ADAPTER:
resultType="Adapter驱动";
break;
case SERVICE_RECOGNIZER_DRIVER:
resultType="Recognizer驱动";
break;
default:
resultType="无法识别";
break;
}
return resultType;
}
else
{
DWORD currentStatus=0;
currentStatus=scm_status[sIndex].ServiceStatus.dwCurrentState;
switch(currentStatus)
{
case SERVICE_RUNNING:
resultStatus="正在运行";
break;
case SERVICE_START_PENDING:
resultStatus="准备启动";
break;
case SERVICE_STOP_PENDING:
resultStatus="准备停止";
break;
case SERVICE_STOPPED:
resultStatus="已经停止";
break;
default:
resultStatus=NULL;
break;
}
return resultStatus;
}
}
//获取服务启动类型--------------------------------------------------------
LPTSTR SerStatus::serConfig(SC_HANDLE scm,int index,int flag,LPENUM_SERVICE_STATUS status)
{
SC_HANDLE scmHander=scm;
int sIndex=index;
BOOL resultFlag=TRUE;
DWORD needbyte=0;
DWORD size;
DWORD error=0;
DWORD starttype=0;
LPTSTR pathname=NULL;
LPTSTR resultString=NULL;
LPQUERY_SERVICE_CONFIG Serconfig;
LPENUM_SERVICE_STATUS scm_status=status;
LPTSTR serviceName=scm_status[sIndex].lpServiceName;
SC_HANDLE sc_h=OpenService(scmHander, serviceName,SERVICE_QUERY_CONFIG);
if (sc_h == NULL)
{
return NULL;
}
if( !QueryServiceConfig(
sc_h,
NULL,
0,
&needbyte))
{
error = GetLastError();
if(error==ERROR_INSUFFICIENT_BUFFER)
{
size=needbyte;
Serconfig=(LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, size);
}
else
{
::CloseServiceHandle(sc_h);
return NULL;
}
}
if( !QueryServiceConfig(
sc_h,
Serconfig,
size,
&needbyte) )
{
::CloseServiceHandle(sc_h);
return NULL;
}
else
{
switch(flag)
{
case SERVICE_STARTTYPE:
starttype=Serconfig->dwStartType;
switch(starttype)
{
case SERVICE_AUTO_START:
resultString="(System)启动";
break;
case SERVICE_BOOT_START:
resultString="(Boot)引导";
break;
case SERVICE_DEMAND_START:
resultString="(startservice)启动";
break;
case SERVICE_SYSTEM_START:
resultString="(IoInitSystem)启动";
break;
case SERVICE_DISABLED:
resultString="无效启动";
break;
default:
resultString="无效服务";
break;
}
break;
case SERVICE_DISC:
resultString=Serconfig->lpDisplayName;
break;
case SERVICE_ACOUNT:
resultString=Serconfig->lpServiceStartName;
break;
case SERVICE_PATH:
resultString=Serconfig->lpBinaryPathName;
break;
default:
return NULL;
}
::LocalFree(Serconfig);
}
return resultString;
}
5.3.heckSerStatus类
//确认服务状态--------------------------------------------------------
int CheckSerStatus::checkStatus(LPTSTR serviceName)
{
int resultFlag=0;
BOOL checkFlag=FALSE;
DWORD currentState=0;
LPSERVICE_STATUS serviceStatus=(LPSERVICE_STATUS)::LocalAlloc(LPTR,28*8);//
sc_open=::OpenService(sc_scm,serviceName,SERVICE_QUERY_STATUS);
if(sc_open!=NULL)
{
checkFlag=::QueryServiceStatus(sc_open,serviceStatus);
if(checkFlag!=TRUE)
{
::LocalFree(serviceStatus);//销毁分配内存--
return 5;
}
else
{
currentState=serviceStatus->dwCurrentState;
switch(currentState)
{
case SERVICE_RUNNING:
resultFlag=1;
break;
case SERVICE_START_PENDING:
resultFlag=2;
break;
case SERVICE_STOP_PENDING:
resultFlag=3;
break;
case SERVICE_STOPPED:
resultFlag=4;
break;
default:
break;
}
::CloseServiceHandle(sc_open);
}
}
else
{
::LocalFree(serviceStatus);//销毁分配内存--
::CloseServiceHandle(sc_open);//销毁句柄--
return 5;
}
::LocalFree(serviceStatus);//销毁分配内存--
::CloseServiceHandle(sc_open);//销毁句柄--
return resultFlag;
}
5.4.Addserv类
//创建驱动服务--------------------------------------------------------
BOOL InstallService::CreateQServ(LPTSTR serviceName,LPTSTR displayName,LPTSTR pathName)
{
BOOL result_scm;
result_scm=this->checkSCM();
if(!result_scm)
{
::MessageBox(NULL,"SCM打开失败,\n无法安装应用程序服务!","警告",MB_OK|MB_ICONERROR);
return result_scm;
}
else
{
SC_HANDLE sc_createEx=::CreateService(sc_scm,serviceName,displayName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,pathName,NULL,NULL,NULL,NULL,NULL);
int error;
if(sc_createEx==NULL)
{
error=::GetLastError();
if(error==ERROR_DUPLICATE_SERVICE_NAME)
{
::MessageBox(NULL,"创建失败提示:\n服务描述重名,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
if(error==ERROR_INVALID_NAME)
{
::MessageBox(NULL,"创建失败提示:\n服务名无效,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
if(error==ERROR_INVALID_SERVICE_ACCOUNT)
{
::MessageBox(NULL,"创建失败提示:\n创建者账户不存在,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
if(error==ERROR_SERVICE_EXISTS||error==ERROR_SERVICE_MARKED_FOR_DELETE)
{
::MessageBox(NULL,"创建失败提示:\n该服务已经创建,请重新创建!","警告",MB_OK|MB_ICONERROR);
::CloseServiceHandle(sc_createEx);//销毁句柄--
return FALSE;
}
}
else
{
this->sc_create=sc_createEx;
::Sleep(50);
::MessageBox(NULL,"创建成功提示:\n该服务创建成功!","提示",MB_OK|MB_ICONWARNING);
::CloseServiceHandle(sc_createEx);//销毁句柄--
::CloseServiceHandle(this->sc_create);
return TRUE;
}
}
}
//启动服务函数--------------------------------------------------------
BOOL InstallService::StartService(LPTSTR serviceName)
{
BOOL result_scm;
CString showInfo=_T("");
BOOL result;
LPSERVICE_STATUS serStatus=(LPSERVICE_STATUS)::LocalAlloc(LPTR,28*8);
result_scm=this->checkSCM();
if(!result_scm)
{
::MessageBox(NULL,"SCM打开失败,\n无法安装应用程序服务!","警告",MB_OK|MB_ICONERROR);
return result_scm;
}
else
{
SC_HANDLE sService =OpenService(sc_scm,serviceName,SERVICE_ALL_ACCESS);
if (sService != NULL)
{
showInfo="是否启动服务:\n【";
showInfo+=serviceName;
showInfo+="】";
if(IDYES==::MessageBox(NULL,showInfo,"询问",MB_YESNO|MB_ICONQUESTION))
{
//--------------------
if(::QueryServiceStatus(sService,serStatus))
{
if(serStatus->dwServiceType==SERVICE_KERNEL_DRIVER||serStatus->dwServiceType==SERVICE_FILE_SYSTEM_DRIVER||serStatus->dwServiceType==SERVICE_RECOGNIZER_DRIVER)
result=::StartService(sService,NULL,NULL);
else
result=::StartService(sService,0,NULL);
}
//--------------------------
if(result==TRUE)
{
if(serStatus->dwCurrentState=SERVICE_START_PENDING||serStatus->dwCurrentState==SERVICE_RUNNING)
{
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】启动成功!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return result;
}
else
{
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】启动失败!";
::MessageBox(NULL,showInfo,"警告",MB_OK|MB_ICONERROR);
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
//-----------------
else
{
int error=::GetLastError();
switch(error)
{
case ERROR_ACCESS_DENIED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】启动权限不够!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_PATH_NOT_FOUND:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】加载路径不存在!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DATABASE_LOCKED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】加载的SCM锁定!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_DELETED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】依赖的服务不存在或已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_FAIL:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】依赖的服务启动失败!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DISABLED:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】不可用!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_MARKED_FOR_DELETE:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_REQUEST_TIMEOUT:
::Sleep(50);
showInfo="服务【";
showInfo+=serviceName;
showInfo+="】已启动,正在注册!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
}
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
//----------------------------------
else
{
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
else
{
::LocalFree(serStatus);//--
::CloseServiceHandle(serStatus);
return FALSE;
}
}
}
//启动服务--------------------------------------------------------
void CEnumserv::OnStartservice()
{
// TODO: Add your control notification handler code here
//--------------------------------
CString itemName;
CString showInfo=_T("");
BOOL result;
char item_name[MAX_PATH-100];
LPSERVICE_STATUS serStatus=(LPSERVICE_STATUS)::LocalAlloc(LPTR,28*8);
this->m_enumlist.GetItemText(this->m_itemIndex,0,item_name,MAX_PATH-100);
itemName=item_name;
if(this->m_sName!=itemName)
{
showInfo="请双击第一列选中";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
::LocalFree(serStatus);
return;
}
else
{
if(!this->m_enumlist.GetCheck(this->m_itemIndex))
{
showInfo="请选中【";
showInfo+=m_sName;
showInfo+="】列的CheckBox框!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
::LocalFree(serStatus);
return;
}
else
{
//-------------------------------
if(sc_handle==NULL)
{
::LocalFree(serStatus);//销毁分配内存--
return;
}
else
{
SC_HANDLE sService =OpenService(sc_handle,m_sName,SERVICE_ALL_ACCESS);
if (sService != NULL)
{
showInfo="是否启动服务:\n【";
showInfo+=this->m_sName;
showInfo+="】";
if(IDYES==::MessageBox(NULL,showInfo,"询问",MB_YESNO|MB_ICONQUESTION))
{
if(::QueryServiceStatus(sService,serStatus))
{
if(serStatus->dwServiceType==SERVICE_KERNEL_DRIVER||serStatus->dwServiceType==SERVICE_FILE_SYSTEM_DRIVER||serStatus->dwServiceType==SERVICE_RECOGNIZER_DRIVER)
result=StartService(sService,NULL,NULL);
else
result=StartService(sService,0,NULL);
}
//-------------------
if(result==TRUE)
{
if(serStatus->dwCurrentState=SERVICE_START_PENDING||serStatus->dwCurrentState==SERVICE_RUNNING)
{
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】启动成功!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONWARNING);
this->m_enumlist.SetItemText(this->m_itemIndex,2,"正在启动");
::LocalFree(serStatus);//--
return;
}
else
{
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】启动失败!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
::LocalFree(serStatus);//--
return;
}
}
else
{
int error=::GetLastError();
switch(error)
{
case ERROR_ACCESS_DENIED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】启动权限不够!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_PATH_NOT_FOUND:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】加载路径不存在!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DATABASE_LOCKED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】加载的SCM锁定!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_DELETED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】依赖的服务不存在或已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DEPENDENCY_FAIL:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】依赖的服务启动失败!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_DISABLED:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】不可用!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_MARKED_FOR_DELETE:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】已做删除标记!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
case ERROR_SERVICE_REQUEST_TIMEOUT:
::Sleep(50);
showInfo="服务【";
showInfo+=m_sName;
showInfo+="】已启动,正在注册!";
::MessageBox(NULL,showInfo,"提示",MB_OK|MB_ICONERROR);
break;
}
::LocalFree(serStatus);//--
}
//-----------------
}
else
{
::LocalFree(serStatus);//--
return;
}
::CloseServiceHandle(sService);//销毁句柄--
}
}
}
}
}
//结束(*^__^*)---【源码下载】:http://127.0.0.1/serConf.exe
相关文章推荐
- 标准库 svc—程序及服务控制
- 浅析android通过jni控制service服务程序的简易流程
- Windows 服务控制管理器通信的命令行程序
- 浅析android通过jni控制service服务程序的简易流程
- Windows Service服务程序的原理及实现(0)服务主函数 & 控制处理函数
- ASP.NET C# 如何在程序中控制IIS服务或应用程序池重启?
- 木其工作室(专业程序代写服务)[原]ok6410学习笔记(16.按键中断控制led驱动)
- MVC下接口程序 响应手机请求的参数设置请求并控制服务程序下发设备参数变更报文
- 在VFP中控制和创建windows 服务程序
- C 语言编写windows服务程序的控制程序
- IIS网站已经停止,提示服务器没有及时响应启动或控制请求!本地计算机法启动 World Wide Web Publishing 服务。提示 “错误127: 找不到指定的程序”或者“错误1721,资源不足,无法启动”
- 控制服务程序
- IIS网站已经停止,提示服务器没有及时响应启动或控制请求!本地计算机法启动 World Wide Web Publishing 服务。提示 “错误127: 找不到指定的程序”或者“错误1721,资源不足,无法启动
- 对NT服务型程序的控制代码。如安装服务、启动、停止服务、取服务状态等。
- 启动和停止服务的控制程序, 网上找的, 稍加改动
- ASP.NET C# 如何在程序中控制IIS服务或应用程序池重启?
- Windows 服务控制管理器通信的命令行程序
- 浅析android通过jni控制service服务程序的简易流程
- 对NT服务型程序的控制代码。如安装服务、启动、停止服务、取服务状态等。
- tartServiceCtrlDispatcher 服务控制管理器(service) 服务控制管理程序接口