前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >驱动开发:实现驱动加载卸载工具

驱动开发:实现驱动加载卸载工具

原创
作者头像
微软技术分享
发布2022-11-20 16:34:15
1.8K0
发布2022-11-20 16:34:15
举报

驱动程序加载工具有许多,最常用的当属KmdManager工具,如果驱动程序需要对外发布那我们必须自己编写实现一个驱动加载工具,当需要使用驱动时可以拉起自己的驱动,如下将实现一个简单的驱动加载工具,该工具可以实现基本的,安装,加载,关闭,卸载等操作日常使用完全没问题。

installDvr 驱动安装

代码语言:c
复制
#include <iostream>
#include <Windows.h>

using namespace std;

// 安装驱动
BOOL installDvr(CONST WCHAR drvPath[50], CONST WCHAR serviceName[20])
{

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
		);
	
	if (schSCManager == NULL)
	{
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 创建服务对象,添加至服务控制管理器数据库
	SC_HANDLE schService = CreateService
		(
		schSCManager,               // 服务控件管理器数据库的句柄
		serviceName,                // 要安装的服务的名称
		serviceName,                // 用户界面程序用来标识服务的显示名称
		SERVICE_ALL_ACCESS,         // 对服务的访问权限:所有全权限
		SERVICE_KERNEL_DRIVER,      // 服务类型:驱动服务
		SERVICE_DEMAND_START,       // 服务启动选项:进程调用 StartService 时启动
		SERVICE_ERROR_IGNORE,       // 如果无法启动:忽略错误继续运行
		drvPath,                    // 驱动文件绝对路径,如果包含空格需要多加双引号
		NULL,                       // 服务所属的负载订购组:服务不属于某个组
		NULL,                       // 接收订购组唯一标记值:不接收
		NULL,                       // 服务加载顺序数组:服务没有依赖项
		NULL,                       // 运行服务的账户名:使用 LocalSystem 账户
		NULL                        // LocalSystem 账户密码
		);
	
	if (schService == NULL)
	{
		CloseServiceHandle(schService);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	CloseServiceHandle(schService);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

int main(int argc, char *argv[])
{
	if (installDvr(L"C:\\WinDDK.sys", L"service") == TRUE)
	{
		cout << "驱动已安装" << endl;
	}

	getchar();
	return 0;
}

startDvr 启动驱动

代码语言:c
复制
#include <iostream>
#include <Windows.h>

using namespace std;

// 启动服务
BOOL startDvr(CONST WCHAR serviceName[20])
{

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager
		(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
		);
	
	if (schSCManager == NULL)
	{
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 打开服务
	SC_HANDLE hs = OpenService
		(
		schSCManager,           // 服务控件管理器数据库的句柄
		serviceName,            // 要打开的服务名
		SERVICE_ALL_ACCESS      // 服务访问权限:所有权限
		);
	
	if (hs == NULL)
	{
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}
	
	if (StartService(hs, 0, 0) == 0)
	{
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	CloseServiceHandle(hs);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

int main(int argc, char *argv[])
{
	if (startDvr(L"service") == TRUE)
	{
		cout << "驱动服务" << endl;
	}

	getchar();
	return 0;
}

stopDvr 停止驱动

代码语言:c
复制
#include <iostream>
#include <Windows.h>

using namespace std;

// 停止服务
BOOL stopDvr(CONST WCHAR serviceName[20])
{

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager
		(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
		);

	if (schSCManager == NULL)
	{
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 打开服务
	SC_HANDLE hs = OpenService
		(
		schSCManager,           // 服务控件管理器数据库的句柄
		serviceName,            // 要打开的服务名
		SERVICE_ALL_ACCESS      // 服务访问权限:所有权限
		);
	
	if (hs == NULL)
	{
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 如果服务正在运行
	SERVICE_STATUS status;
	if (QueryServiceStatus(hs, &status) == 0)
	{
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	if (status.dwCurrentState != SERVICE_STOPPED &&
		status.dwCurrentState != SERVICE_STOP_PENDING
		)
	{
		// 发送关闭服务请求
		if (ControlService(
			hs,                         // 服务句柄
			SERVICE_CONTROL_STOP,       // 控制码:通知服务应该停止
			&status                     // 接收最新的服务状态信息
			) == 0) {
			CloseServiceHandle(hs);
			CloseServiceHandle(schSCManager);
			return FALSE;
		}

		// 判断超时
		INT timeOut = 0;
		while (status.dwCurrentState != SERVICE_STOPPED)
		{
			timeOut++;
			QueryServiceStatus(hs, &status);
			Sleep(50);
		}

		if (timeOut > 80)
		{
			CloseServiceHandle(hs);
			CloseServiceHandle(schSCManager);
			return FALSE;
		}
	}

	CloseServiceHandle(hs);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

int main(int argc, char *argv[])
{
	if (stopDvr(L"service") == TRUE)
	{
		cout << "停止驱动服务" << endl;
	}

	getchar();
	return 0;
}

unloadDvr 卸载驱动

代码语言:c
复制
#include <iostream>
#include <Windows.h>

using namespace std;

// 卸载驱动
BOOL unloadDvr(CONST WCHAR serviceName[20])
{

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager
		(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
		);

	if (schSCManager == NULL)
	{
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 打开服务
	SC_HANDLE hs = OpenService
		(
		schSCManager,           // 服务控件管理器数据库的句柄
		serviceName,            // 要打开的服务名
		SERVICE_ALL_ACCESS      // 服务访问权限:所有权限
		);

	if (hs == NULL)
	{
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 删除服务
	if (DeleteService(hs) == 0)
	{
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	CloseServiceHandle(hs);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

int main(int argc, char *argv[])
{
	if (unloadDvr(L"service") == TRUE)
	{
		cout << "卸载驱动服务" << endl;
	}

	getchar();
	return 0;
}

封装cDrvCtrl通信类

代码语言:c
复制
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <Windows.h>

#pragma comment(lib,"user32.lib")
#pragma comment(lib,"advapi32.lib")

// ------------------------------------------------------------------------------
// 驱动控制类
// ------------------------------------------------------------------------------

class cDrvCtrl
{
public:
	cDrvCtrl()
	{
		m_pSysPath = NULL;
		m_pServiceName = NULL;
		m_pDisplayName = NULL;
		m_hSCManager = NULL;
		m_hService = NULL;
		m_hDriver = INVALID_HANDLE_VALUE;
	}
	~cDrvCtrl()
	{
		CloseServiceHandle(m_hService);
		CloseServiceHandle(m_hSCManager);
		CloseHandle(m_hDriver);
	}

	// 安装驱动
	BOOL Install(PCHAR pSysPath, PCHAR pServiceName, PCHAR pDisplayName)
	{
		m_pSysPath = pSysPath;
		m_pServiceName = pServiceName;
		m_pDisplayName = pDisplayName;
		m_hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
		if (NULL == m_hSCManager)
		{
			m_dwLastError = GetLastError();
			return FALSE;
		}
		m_hService = CreateServiceA(m_hSCManager, m_pServiceName, m_pDisplayName,
			SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
			m_pSysPath, NULL, NULL, NULL, NULL, NULL);
		if (NULL == m_hService)
		{
			m_dwLastError = GetLastError();
			if (ERROR_SERVICE_EXISTS == m_dwLastError)
			{
				m_hService = OpenServiceA(m_hSCManager, m_pServiceName, SERVICE_ALL_ACCESS);
				if (NULL == m_hService)
				{
					CloseServiceHandle(m_hSCManager);
					return FALSE;
				}
			}
			else
			{
				CloseServiceHandle(m_hSCManager);
				return FALSE;
			}
		}
		return TRUE;
	}

	// 启动驱动
	BOOL Start()
	{
		if (!StartServiceA(m_hService, NULL, NULL))
		{
			m_dwLastError = GetLastError();
			return FALSE;
		}
		return TRUE;
	}

	// 关闭驱动
	BOOL Stop()
	{
		SERVICE_STATUS ss;
		GetSvcHandle(m_pServiceName);
		if (!ControlService(m_hService, SERVICE_CONTROL_STOP, &ss))
		{
			m_dwLastError = GetLastError();
			return FALSE;
		}
		return TRUE;
	}

	// 移除驱动
	BOOL Remove()
	{
		GetSvcHandle(m_pServiceName);
		if (!DeleteService(m_hService))
		{
			m_dwLastError = GetLastError();
			return FALSE;
		}
		return TRUE;
	}

	// 打开驱动
	BOOL Open(PCHAR pLinkName)
	{
		if (m_hDriver != INVALID_HANDLE_VALUE)
			return TRUE;
		m_hDriver = CreateFileA(pLinkName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
		if (m_hDriver != INVALID_HANDLE_VALUE)
			return TRUE;
		else
			return FALSE;
	}

	// 安装并运行驱动
	VOID InstallAndRun()
	{
		char szSysFile[MAX_PATH] = { 0 };
		char szSvcLnkName[] = "LyInject";;
		GetAppPath(szSysFile);
		strcat(szSysFile, "LyInject.sys");

		Install(szSysFile, szSvcLnkName, szSvcLnkName);
		Start();
		Open("\\\\.\\LyInject");
	}

	// 移除并关闭驱动
	VOID RemoveAndStop()
	{
		Stop();
		Remove();
		CloseHandle(m_hDriver);
	}

	// 发送控制信号
	BOOL IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes)
	{
		DWORD dw;
		BOOL b = DeviceIoControl(m_hDriver, CTL_CODE_GEN(dwIoCode), InBuff, InBuffLen, OutBuff, OutBuffLen, &dw, NULL);
		if (RealRetBytes)
			*RealRetBytes = dw;
		return b;
	}
private:
	// 获取服务句柄
	BOOL GetSvcHandle(PCHAR pServiceName)
	{
		m_pServiceName = pServiceName;
		m_hSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
		if (NULL == m_hSCManager)
		{
			m_dwLastError = GetLastError();
			return FALSE;
		}
		m_hService = OpenServiceA(m_hSCManager, m_pServiceName, SERVICE_ALL_ACCESS);
		if (NULL == m_hService)
		{
			CloseServiceHandle(m_hSCManager);
			return FALSE;
		}
		else
		{
			return TRUE;
		}
	}

	// 获取控制信号对应字符串
	DWORD CTL_CODE_GEN(DWORD lngFunction)
	{
		return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED;
	}

	// 获取完整路径
	void GetAppPath(char *szCurFile)
	{
		GetModuleFileNameA(0, szCurFile, MAX_PATH);
		for (SIZE_T i = strlen(szCurFile) - 1; i >= 0; i--)
		{
			if (szCurFile[i] == '\\')
			{
				szCurFile[i + 1] = '\0';
				break;
			}
		}
	}

public:
	DWORD m_dwLastError;
	PCHAR m_pSysPath;
	PCHAR m_pServiceName;
	PCHAR m_pDisplayName;
	HANDLE m_hDriver;
	SC_HANDLE m_hSCManager;
	SC_HANDLE m_hService;
};

int main(int argc, char *argv[])
{
	cDrvCtrl DriveControl;
	DriveControl.InstallAndRun();

	DriveControl.RemoveAndStop();

	system("pause");
	return 0;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档