如何在 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_START0x00000002 | 服务由服务控制管理器在系统启动期间自动启动。 有关更多信息,请参阅 自动启动服务。 | 
| SERVICE_BOOT_START0x00000000 | 由系统加载程序启动的设备驱动程序。 此值仅对驱动程序服务有效。 | 
| SERVICE_DEMAND_START0x00000003 | 当进程调用 StartService函数时,由服务控制管理器启动的服务。 有关更多信息,请参阅 按需启动服务。 | 
| SERVICE_DISABLED0x00000004 | 无法启动的服务。 尝试启动服务将导致错误代码 ERROR_SERVICE_DISABLED。 | 
| SERVICE_SYSTEM_START0x00000001 | 由 IoInitSystem函数启动的设备驱动程序。 此值仅对驱动程序服务有效。 | 


