如何在 Windows 上动态安装驱动程序或将驱动程序安装为服务






3.85/5 (7投票s)
动态安装驱动程序或将驱动程序安装为 Windows 服务。
引言
通常,当我们完成驱动程序编译后,会使用 inf 文件来安装驱动程序。但有时我们希望动态安装驱动程序或将驱动程序安装为 Windows 服务。 在本文中,我们假设驱动程序已经编译并可以直接使用。 驱动程序必须具有 32 位和 64 位版本,以便我们可以在 32 位和 64 位操作系统下进行实验。 如何编译驱动程序不是本文的任务。
关于将要安装的驱动程序文件的路径:通常,我们可以将安装程序和驱动程序文件放在同一目录中。 在大多数情况下,这是可行的。 但是,如果您想在 64 位操作系统环境下将驱动程序安装为 Windows 服务,则会失败。 在这种情况下,驱动程序文件的目录必须是“C:\\Windows\\System32\\drivers”,因此我们使用“C:\\Windows\\System32\\drivers”而不是当前目录。 驱动程序文件会提前复制到该目录。
使用代码
- 安装驱动程序调用函数
GJ_Install_ADL_Driver_BOOT_START()
。 卸载驱动程序调用函数GJ_Uninstall_ADL_Driver()
。 - 设置驱动程序文件目录参考函数
SetupDriverName
。 如何设置当前路径的代码可以在完整的源代码中找到。 - 动态安装驱动程序或将驱动程序安装为服务的关键是 API 函数
CreateService
。
代码示例
//
#include "install.h"
void CInstall_ADL_driver_BOOT_STARTDlg::OnBnClickedIntsall()
{
// TODO: Add your control notification handler code here
//Because if the current OS is 64bit,gjglly.sys must
//copy to "C:\\Windows\\System32\\drivers",
//so we use "C:\\Windows\\System32\\drivers" instead of current directory.
//Refer to function SetupDriverName.
GJ_Install_ADL_Driver_BOOT_START();
}
void CInstall_ADL_driver_BOOT_STARTDlg::OnBnClickedUninstall()
{
// TODO: Add your control notification handler code here
GJ_Uninstall_ADL_Driver();
}//
//
BOOLEAN
SetupDriverName(
__inout_bcount_full(BufferLength) PCHAR DriverLocation,
__in ULONG BufferLength
)
{
HANDLE fileHandle;
DWORD driverLocLen = 0;
//
//
//Because if the current OS is 64bit,gjglly.sys must copy to "C:\\Windows\\System32\\drivers",
//so we use "C:\\Windows\\System32\\drivers" instead of current directory.
//
//
/* //Get the current directory.
GetModuleFileNameA(GetModuleHandle(NULL), DriverLocation, BufferLength);
char* pszSlash = strrchr(DriverLocation, '\\');
pszSlash[0]=0;
*///Get the current directory.
//
GetSystemDirectory(DriverLocation, BufferLength);//"C:\\Windows\\System32\\drivers"
//
//
// Setup path name to driver file.
//
//if (FAILED( StringCbCatA(DriverLocation, BufferLength,
// "<a href="file://%22driver_name%22.sys/">\\"DRIVER_NAME".sys</a>") )) //Get the current directory.
if (FAILED( StringCbCatA(DriverLocation, BufferLength,
"<a href="file://drivers//%22DRIVER_NAME%22.sys">\\drivers\\"DRIVER_NAME".sys</a>") ))
{
return FALSE;
}
//
//Following code will failed in 64bit OS
/*
//
// Insure driver file is in the specified directory.
//
//
//
if ((fileHandle = CreateFileA(DriverLocation,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
)) == INVALID_HANDLE_VALUE) {
//
//
//printf("%s.sys is not loaded.\n", DRIVER_NAME);
//
//
// Indicate failure.
//
//
return FALSE;
}
//
//
// Close open file handle.
//
//
if (fileHandle) {
CloseHandle(fileHandle);
}
//
// Indicate success.
//
*/
//
return TRUE;
//
} // SetupDriverName
//
//
schService = CreateService(SchSCManager, // handle of service control manager database
DriverName, // address of name of service to start
DriverName, // address of display name
SERVICE_ALL_ACCESS, // type of access to service
SERVICE_KERNEL_DRIVER, // type of service
SERVICE_BOOT_START, // when to start service !!! SERVICE_DEMAND_START SERVICE_AUTO_START
SERVICE_ERROR_NORMAL, // severity if service fails to start
ServiceExe, // address of name of binary file
NULL, // service does not belong to a group
NULL, // no tag requested
NULL, // no dependency names
NULL, // use LocalSystem account
NULL // no password for service account
);
//
您可以更改第六个参数“dwStartType
”来设置启动类型。
dwStartType [in]
服务启动选项可以是以下值之一
值 | 含义 |
SERVICE_AUTO_START 0x00000002 |
服务由服务控制管理器在系统启动期间自动启动。 有关更多信息,请参阅 自动启动服务。 |
SERVICE_BOOT_START 0x00000000 |
由系统加载程序启动的设备驱动程序。 此值仅对驱动程序服务有效。 |
SERVICE_DEMAND_START 0x00000003 |
当进程调用 StartService 函数时,由服务控制管理器启动的服务。 有关更多信息,请参阅 按需启动服务。 |
SERVICE_DISABLED 0x00000004 |
无法启动的服务。 尝试启动服务将导致错误代码 ERROR_SERVICE_DISABLED 。 |
SERVICE_SYSTEM_START 0x00000001 |
由 IoInitSystem 函数启动的设备驱动程序。 此值仅对驱动程序服务有效。 |