利用API函数加载系统服务以加载驱动
基础知识:
一个服务由三部分组成,第一部分是Service Control Manager(SCM)。每个Windows NT/2000系统都有一个SCM,SCM存在于Service.exe中,在Windows启动的时候会自动运行,伴随着操作系统的启动和关闭而产生和终止。这个进程以系统特权运行,并且提供一个统一的、安全的手段去控制服务。它其实是一个RPC Server,因此我们可以远程安装和管理服务,不过这不在本文讨论的范围之内。SCM包含一个储存着已安装的服务和驱动程序的信息的数据库,通过SCM可以统一的、安全的管理这些信息,因此一个服务程序的安装过程就是将自身的信息写入这个数据库。
第二部分就是服务本身。一个服务拥有能从SCM收到信号和命令所必需的的特殊代码,并且能够在处理后将它的状态回传给SCM。
第三部分也就是最后一部分,是一个Service Control Dispatcher(SCP)。它是一个拥有用户界面,允许用户开始、停止、暂停、继续,并且控制一个或多个安装在计算机上服务的Win32应用程序。SCP的作用是与SCM通讯,Windows 2000管理工具中的“服务”就是一个典型的SCP。
由于要写的只是一个驱动服务,所以理解起来简单很多。
需要实现两个函数,一个安装,一个卸载
例子:
BOOL InstallNtDriver(LPCTSTR lpServiceName, LPCTSTR lpBinaryPathName);
BOOL UninstallNtDriver(LPCTSTR lpServiceName);
最好 lpServiceName和lpBinaryPathName 指向为 256 字节的字符数组
char szServiceName[256] = {0}; 例如:first.sys
char szBinaryPathName[256] = {0}; 例如:D:/sys/first.sys
1 安装服务加载驱动
第一步:打开服务控制管理 Service Control Manager
OpenSCManager();
第二步:创建服务
CreateService();
第三步:如果服务已经存在,就打开相应服务
OpenService();
第四部:启动服务
StartService();
第五步:关闭第一、二、三步产生的句柄
CloseServiceHandle();
2 卸载服务以及其驱动
第一步:打开服务控制管理 Service Control Manager
OpenSCManager();
第二步:打开相应服务
OpenService();
第三步:停止服务
ControlService();
第四步:删除服务
DeleteService();
第五步:关闭第一、二步产生的句柄
CloseServiceHandle();
下面是对上述函数的参数的常用选择:
SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName, // computer name 为NULL就是本机
LPCTSTR lpDatabaseName, // SCM database name 使用默认数据库就为NULL
DWORD dwDesiredAccess //access type 所有权限
);
例子:hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
*********************************分割线***************************
SC_HANDLE CreateService(
SC_HANDLE hSCManager, // handle to SCM database
LPCTSTR lpServiceName, // name of service to start
LPCTSTR lpDisplayName, // display name
DWORD dwDesiredAccess, // type of access to service
DWORD dwServiceType, // type of service 这里要选择驱动服务
DWORD dwStartType, // when to start service
DWORD dwErrorControl, // severity of service failure 选择忽略错误继续
LPCTSTR lpBinaryPathName, // name of binary file 驱动文件的绝对路径
LPCTSTR lpLoadOrderGroup, // name of load ordering group
LPDWORD lpdwTagId, // tag identifier
LPCTSTR lpDependencies, // array of dependency names
LPCTSTR lpServiceStartName, // account name
LPCTSTR lpPassword // account password
)
在GetLastError();后要注意
若果:DWORD lastError = GetLastError();
(ERROR_IO_PENDING != lastError && ERROR_SERVICE_EXISTS != lastError)
就是说服务可能已经存在了,可以调用OpenService()来打开服务。
一般上最后五个参数为空:
例子:hService = CreateService(hSCM,
lpServiceName,
lpServiceName,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
lpBinaryPathName,
NULL,NULL,NULL,NULL,NULL);
*********************************分割线***************************
SC_HANDLE OpenService(
SC_HANDLE hSCManager, // handle to SCM database
LPCTSTR lpServiceName, // service name
DWORD dwDesiredAccess // access 一般为所有权限
);
例子:
hService = OpenService(hSCM, lpServiceName, SERVICE_ALL_ACCESS);
*********************************分割线***************************
BOOL StartService(
SC_HANDLE hService, // handle to service
DWORD dwNumServiceArgs, // number of arguments 参数个数
LPCTSTR *lpServiceArgVectors // array of arguments 参数指针
);
一般这里不用传入参数
例子:
bFlag = StartService(hService, 0, NULL);
*********************************分割线***************************
BOOL ControlService(
SC_HANDLE hService, // handle to service
DWORD dwControl, // control code 选择操作启动停止等
LPSERVICE_STATUS lpServiceStatus // status information 输出的一个服务状态
);
例子:SERVICE_STATUS srvStatus;
bFlag = ControlService(hService, SERVICE_CONTROL_STOP, &srvStatus);
*********************************分割线***************************
BOOL DeleteService(
SC_HANDLE hService // handle to service
);
*********************************分割线***************************
BOOL CloseServiceHandle(
SC_HANDLE hSCObject // handle to service or SCM object
);
*********************************分割线***************************