驱动装载和卸载的过程
驱动的装载和卸载依靠于服务,安装一个驱动等同于安装一个服务
在操作服务的过程中,在不使用服务相关的句柄时要及时释放
驱动的装载
- 打开服务管理器
- 创建驱动的服务
- 启动服务
驱动的卸载
- 打开服务管理器
- 打开驱动的服务
- 停止服务
- 删除服务
相关API
打开服务管理器
SC_HANDLE OpenSCManagerA( LPCSTR lpMachineName, // 目标计算机的名称,为NULL则是本地 LPCSTR lpDatabaseName, // 数据库的名称,为NULL则默认打开SERVICES_ACTIVE_DATABASE数据库 DWORD dwDesiredAccess // 访问控制,为SC_MANAGER_ALL_ACCESS则是所有权限 ); // 成功返回服务管理器句柄,失败则为NULL
创建或打开服务
SC_HANDLE CreateServiceA( SC_HANDLE hSCManager, // 服务管理器句柄 LPCSTR lpServiceName, // 服务名称 LPCSTR lpDisplayName, // 显示名称 DWORD dwDesiredAccess, // 访问控制,SERVICE_ALL_ACCESS为所有权限 DWORD dwServiceType, // 服务类型,SERVICE_KERNEL_DRIVER为内核驱动 DWORD dwStartType, // 启动类型,SERVICE_DEMAND_START为后续调用StartService才启动 DWORD dwErrorControl, // 如果此服务无法启动,则错误的严重程度和所采取的操作,SERVICE_ERROR_NORMAL为默认 LPCSTR lpBinaryPathName, // 驱动路径 LPCSTR lpLoadOrderGroup, // 服务所属组名,可为NULL LPDWORD lpdwTagId, // 可为NULL LPCSTR lpDependencies, // 可为NULL LPCSTR lpServiceStartName, // 服务应该在其下运行的帐户的名称,可为NULL LPCSTR lpPassword // 账户密码,,可为NULL ); // CreateService成功返回服务句柄,失败则返回NULL SC_HANDLE OpenServiceA( SC_HANDLE hSCManager, // 服务管理器句柄 LPCSTR lpServiceName, // 服务名称 DWORD dwDesiredAccess // 访问控制 ); // OpenService成功返回服务句柄,失败则返回NULL
启动服务
BOOL StartServiceA( SC_HANDLE hService, // 服务句柄 DWORD dwNumServiceArgs, // lpServiceArgVectors数组的个数,可为0 LPCSTR *lpServiceArgVectors // 可为NULL );
停止与卸载服务
// 控制服务 BOOL ControlService( SC_HANDLE hService, // 服务句柄 DWORD dwControl, // SERVICE_CONTROL_STOP为停止 LPSERVICE_STATUS lpServiceStatus // SERVICE_STATUS结构的指针 ); BOOL DeleteService( SC_HANDLE hService // 服务句柄 );
关闭服务句柄
BOOL CloseServiceHandle( SC_HANDLE hSCObject // 服务句柄 );
实现DriverManager类
/**************************DriverManager.h*********************************/
#ifndef DRIVERMANAGER_H
#define DRIVERMANAGER_H
#include <Windows.h>
#define SERVICE_NAME TEXT("MyHunter") // 服务名
#define SERVICE_SHOW SERVICE_NAME // 服务显示名
class DriverManager
{
public:
DriverManager();
virtual ~DriverManager();
bool install_driver(); // 安装驱动
bool start_driver(); // 启动驱动
bool stop_driver(); // 停止驱动
bool uninstall_driver(); // 卸载驱动
bool connect_driver(const TCHAR *symbol_name); // 链接驱动
void disconnect_driver();
/*
* 驱动控制
* control_code: 控制码
* in_buf:输入缓冲区
* in_buf_size:输入缓冲区大小
* out_buf:输出缓冲区
* out_buf_size:输出缓冲区大小
* ret_bytes:返回字节数
*/
bool io_control(DWORD control_code, LPVOID in_buf,
DWORD in_buf_size, LPVOID out_buf, DWORD out_buf_size, LPDWORD ret_bytes);
void set_driver(const TCHAR *path); // 设置驱动路径
inline DWORD get_last_error() const { return last_error_; } // 获取错误码
private:
TCHAR *driver_path = nullptr; // 驱动路径
SC_HANDLE scm_manager_ = nullptr; // 服务管理器句柄
SC_HANDLE service_ = nullptr; // 服务句柄
HANDLE driver_ = INVALID_HANDLE_VALUE; // 驱动句柄
DWORD last_error_ = 0; // 错误码
};
#endif // DRIVERMANAGER_H
/**************************DriverManager.cpp*********************************/
#include "drivermanager.h"
#include <tchar.h>
DriverManager::DriverManager()
{
}
DriverManager::~DriverManager()
{
// 清理资源
if (driver_path)
delete[] driver_path;
if (service_)
::CloseServiceHandle(service_);
if (scm_manager_)
::CloseServiceHandle(scm_manager_);
}
bool DriverManager::install_driver()
{
// 建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库
scm_manager_ = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(!scm_manager_) {
// 获取错误码
last_error_ = ::GetLastError();
return false;
}
// 创建服务
service_ = ::CreateService(scm_manager_, SERVICE_NAME, SERVICE_SHOW, SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driver_path,
nullptr, nullptr, nullptr, nullptr, nullptr);
if(!service_) {
// 获取错误码并关闭服务管理器句柄
last_error_ = ::GetLastError();
::CloseServiceHandle(scm_manager_);
scm_manager_ = nullptr;
return false;
}
// 关闭句柄
::CloseServiceHandle(service_);
::CloseServiceHandle(scm_manager_);
service_ = nullptr;
scm_manager_ = nullptr;
return true;
}
bool DriverManager::start_driver()
{
// 建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库
scm_manager_ = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!scm_manager_) {
// 获取错误码
last_error_ = ::GetLastError();
return false;
}
// 打开现有服务
service_ = ::OpenService(scm_manager_, SERVICE_NAME, SERVICE_ALL_ACCESS);
if (!service_) {
// 获取错误码并关闭服务管理器句柄
last_error_ = ::GetLastError();
::CloseServiceHandle(scm_manager_);
scm_manager_ = nullptr;
return false;
}
// 启动服务
bool ret = ::StartService(service_, 0, nullptr);
if(!ret) {
// 启动失败,获取错误码
last_error_ = ::GetLastError();
}
// 关闭句柄
::CloseServiceHandle(service_);
::CloseServiceHandle(scm_manager_);
service_ = nullptr;
scm_manager_ = nullptr;
return ret;
}
bool DriverManager::stop_driver()
{
// 建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库
scm_manager_ = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!scm_manager_) {
// 获取错误码
last_error_ = ::GetLastError();
return false;
}
// 打开现有服务
service_ = ::OpenService(scm_manager_, SERVICE_NAME, SERVICE_ALL_ACCESS);
if (!service_) {
// 获取错误码并关闭服务管理器句柄
last_error_ = ::GetLastError();
::CloseServiceHandle(scm_manager_);
scm_manager_ = nullptr;
return false;
}
// 停止服务
SERVICE_STATUS status = { 0 };
bool ret = ::ControlService(service_, SERVICE_CONTROL_STOP, &status);
if (!ret) {
// 启动失败,获取错误码
last_error_ = ::GetLastError();
}
// 关闭句柄
::CloseServiceHandle(service_);
::CloseServiceHandle(scm_manager_);
service_ = nullptr;
scm_manager_ = nullptr;
return ret;
}
bool DriverManager::uninstall_driver()
{
// 建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库
scm_manager_ = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!scm_manager_) {
// 获取错误码
last_error_ = ::GetLastError();
return false;
}
// 打开现有服务
service_ = ::OpenService(scm_manager_, SERVICE_NAME, SERVICE_ALL_ACCESS);
if (!service_) {
// 获取错误码并关闭服务管理器句柄
last_error_ = ::GetLastError();
::CloseServiceHandle(scm_manager_);
scm_manager_ = nullptr;
return false;
}
bool ret = ::DeleteService(service_);
if (!ret) {
// 启动失败,获取错误码
last_error_ = ::GetLastError();
}
// 关闭句柄
::CloseServiceHandle(service_);
::CloseServiceHandle(scm_manager_);
service_ = nullptr;
scm_manager_ = nullptr;
return ret;
}
bool DriverManager::connect_driver(const TCHAR *symbol_name)
{
// 连接驱动
driver_ = ::CreateFile(symbol_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(driver_ == INVALID_HANDLE_VALUE) {
// 连接失败,获取返回值
last_error_ = ::GetLastError();
return false;
}
return true;
}
void DriverManager::disconnect_driver()
{
if(driver_ != INVALID_HANDLE_VALUE)
::CloseHandle(driver_);
}
bool DriverManager::io_control(DWORD control_code, LPVOID in_buf, DWORD in_buf_size, LPVOID out_buf, DWORD out_buf_size,
LPDWORD ret_bytes)
{
if(!::DeviceIoControl(driver_, control_code, in_buf, in_buf_size, out_buf, out_buf_size, ret_bytes, NULL)) {
last_error_ = ::GetLastError();
return false;
}
return true;
}
void DriverManager::set_driver(const TCHAR *path)
{
// 释放空间
if (driver_path)
delete[] driver_path;
// 申请空间
DWORD length = _tcslen(path);
DWORD bytes = (length + 1) * sizeof(TCHAR);
driver_path = new TCHAR[bytes];
// 拷贝字符串
_tcsncpy(driver_path, path, length + 1);
}