驱动程序加载工具有许多,最常用的当属KmdManager
工具,如果驱动程序需要对外发布那我们必须自己编写实现一个驱动加载工具,当需要使用驱动时可以拉起自己的驱动,如下将实现一个简单的驱动加载工具,该工具可以实现基本的,安装,加载,关闭,卸载等操作日常使用完全没问题。
驱动安装
OpenSCManager是Windows操作系统提供的一个函数,用于打开服务控制管理器(SCM)数据库。服务控制管理器是Windows系统中的一个组件,负责管理和控制系统中的各种服务。
以下是OpenSCManager函数的基本信息:
SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName,
LPCTSTR lpDatabaseName,
DWORD dwDesiredAccess
);
参数说明:
- lpMachineName:机器名称,指定要连接的远程机器名称,如果为NULL,则表示本地机器。
- lpDatabaseName:数据库名称,指定要打开的服务数据库的名称。常用的取值有SERVICES_ACTIVE_DATABASE和SERVICES_FAILED_DATABASE。
- dwDesiredAccess:访问权限,指定打开服务控制管理器的访问权限。
返回值:
- 返回一个SC_HANDLE类型的句柄,表示打开的服务控制管理器的句柄。如果打开失败,返回NULL。
通过调用OpenSCManager函数,可以获取一个服务控制管理器的句柄,进而可以对服务进行管理和控制,如创建服务、打开已有的服务等。打开服务控制管理器需要适当的权限,通常需要以管理员身份运行。
CreateService是Windows操作系统提供的一个函数,用于创建一个新的服务。服务是在Windows操作系统中以后台方式运行的程序,可以在系统启动时自动启动,并在后台提供某种功能或服务。
以下是CreateService函数的基本信息:
SC_HANDLE CreateService(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
LPCTSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCTSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCTSTR lpDependencies,
LPCTSTR lpServiceStartName,
LPCTSTR lpPassword
);
参数说明:
- hSCManager:服务控制管理器的句柄,用于操作服务管理器。
- lpServiceName:服务的名称,用于唯一标识一个服务。
- lpDisplayName:服务的显示名称,用于在用户界面上显示的友好名称。
- dwDesiredAccess:服务的访问权限。
- dwServiceType:服务的类型,可以是服务、驱动程序等。
- dwStartType:服务的启动类型,指定服务在系统启动时的启动方式。
- dwErrorControl:服务的错误控制,指定服务出错时的处理方式。
- lpBinaryPathName:服务的可执行文件路径。
- lpLoadOrderGroup:服务的加载顺序组,用于指定服务的加载顺序。
- lpdwTagId:服务标识号的指针,用于接收新创建服务的标识号。
- lpDependencies:服务依赖项,指定服务所依赖的其他服务。
- lpServiceStartName:服务的启动用户名。
- lpPassword:服务的启动密码。
返回值:
- 返回一个SC_HANDLE类型的句柄,表示创建的服务的句柄。如果创建失败,返回NULL。
通过调用CreateService函数,可以在系统中创建一个新的服务,并指定该服务的各种属性和配置。创建服务需要适当的权限,通常需要以管理员身份运行。
#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;
}
启动驱动
OpenService是Windows操作系统提供的一个函数,用于打开一个已存在的服务。
以下是OpenService函数的基本信息:
SC_HANDLE OpenService(
SC_HANDLE hSCManager,
LPCTSTR lpServiceName,
DWORD dwDesiredAccess
);
参数说明:
- hSCManager:服务控制管理器句柄,通过调用OpenSCManager函数获取到的服务控制管理器句柄。
- lpServiceName:服务名称,指定要打开的服务的名称。
- dwDesiredAccess:访问权限,指定打开服务的访问权限。
返回值:
- 返回一个SC_HANDLE类型的句柄,表示打开的服务的句柄。如果打开失败,返回NULL。
通过调用OpenService函数,可以获取一个已存在服务的句柄,进而可以对该服务进行操作,如启动、停止、删除等。打开服务需要适当的权限,通常需要以管理员身份运行,并且服务必须已经存在于服务控制管理器中。
#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;
}
停止驱动
QueryServiceStatus是Windows操作系统提供的一个函数,用于查询指定服务的当前状态。
以下是QueryServiceStatus函数的基本信息:
BOOL QueryServiceStatus(
SC_HANDLE hService,
LPSERVICE_STATUS lpServiceStatus
);
参数说明:
- hService:服务句柄,通过调用OpenService函数获取到的已打开服务的句柄。
- lpServiceStatus:指向SERVICE_STATUS结构体的指针,用于接收查询到的服务状态信息。
返回值:
- 如果函数调用成功,返回非零值(TRUE);如果函数调用失败,返回零值(FALSE)。可以通过调用GetLastError函数获取更多错误信息。
通过调用QueryServiceStatus函数,可以获取指定服务的当前状态信息,包括服务的运行状态、运行时间、最后一次错误等。通过查询服务状态,可以判断服务是否正在运行、停止或处于其他状态,并根据需要进行相应的处理。
ControlService是Windows操作系统提供的一个函数,用于控制指定服务的操作,例如启动、停止、暂停、恢复等。
以下是ControlService函数的基本信息:
BOOL ControlService(
SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus
);
参数说明:
- hService:服务句柄,通过调用OpenService函数获取到的已打开服务的句柄。
- dwControl:控制码,用于指定要执行的操作,可以是以下常量之一:
- SERVICE_CONTROL_STOP:停止服务。
- SERVICE_CONTROL_PAUSE:暂停服务。
- SERVICE_CONTROL_CONTINUE:继续服务。
- SERVICE_CONTROL_INTERROGATE:查询服务状态。
其他自定义的控制码。
- lpServiceStatus:指向SERVICE_STATUS结构体的指针,用于接收操作后的服务状态信息。
返回值:
- 如果函数调用成功,返回非零值(TRUE);如果函数调用失败,返回零值(FALSE)。可以通过调用GetLastError函数获取更多错误信息。
通过调用ControlService函数,可以对指定的服务进行不同的操作,例如启动服务、停止服务、暂停服务、恢复服务等。可以根据需要选择不同的控制码来执行相应的操作,并通过接收的服务状态信息来判断操作是否成功。
#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;
}
卸载驱动
DeleteService是Windows操作系统提供的一个函数,用于删除指定的服务。
以下是DeleteService函数的基本信息:
BOOL DeleteService(
SC_HANDLE hService
);
参数说明:
- hService:服务句柄,通过调用OpenService函数获取到的已打开服务的句柄。
返回值:
- 如果函数调用成功,返回非零值(TRUE);如果函数调用失败,返回零值(FALSE)。可以通过调用GetLastError函数获取更多错误信息。
通过调用DeleteService函数,可以删除指定的服务。在调用此函数之前,需要先通过OpenSCManager和OpenService函数获取到相应的服务句柄。删除服务后,该服务将从系统中完全移除,无法再进行操作。
#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;
}