内核编程学习笔记(002) 利用API函数加载系统服务以加载驱动

来源:互联网 发布:Ubuntu mysql安装教程 编辑:程序博客网 时间:2024/06/06 03:52

利用API函数加载系统服务以加载驱动

基础知识:

一个服务由三部分组成,第一部分是Service Control Manager(SCM)。每个Windows NT/2000系统都有一个SCMSCM存在于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);

最好 lpServiceNamelpBinaryPathName 指向为 256 字节的字符数组

char szServiceName[256] = {0};   例如:first.sys

char szBinaryPathName[256] = {0}; 例如:D:/sys/first.sys

安装服务加载驱动

第一步:打开服务控制管理 Service Control Manager

OpenSCManager();

第二步:创建服务

CreateService();

第三步:如果服务已经存在,就打开相应服务

OpenService();

第四部:启动服务

StartService();

第五步:关闭第一、二、三步产生的句柄

CloseServiceHandle();

卸载服务以及其驱动

第一步:打开服务控制管理 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

);

*********************************分割线***************************