65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.85/5 (7投票s)

2011年12月2日

CPOL

2分钟阅读

viewsIcon

61960

downloadIcon

4376

动态安装驱动程序或将驱动程序安装为 Windows 服务。

引言

通常,当我们完成驱动程序编译后,会使用 inf 文件来安装驱动程序。但有时我们希望动态安装驱动程序或将驱动程序安装为 Windows 服务。 在本文中,我们假设驱动程序已经编译并可以直接使用。 驱动程序必须具有 32 位和 64 位版本,以便我们可以在 32 位和 64 位操作系统下进行实验。 如何编译驱动程序不是本文的任务。

关于将要安装的驱动程序文件的路径:通常,我们可以将安装程序和驱动程序文件放在同一目录中。 在大多数情况下,这是可行的。 但是,如果您想在 64 位操作系统环境下将驱动程序安装为 Windows 服务,则会失败。 在这种情况下,驱动程序文件的目录必须是“C:\\Windows\\System32\\drivers”,因此我们使用“C:\\Windows\\System32\\drivers”而不是当前目录。 驱动程序文件会提前复制到该目录。

Install_ADL_driver_BOOT_START.JPG

使用代码

  1. 安装驱动程序调用函数 GJ_Install_ADL_Driver_BOOT_START()。 卸载驱动程序调用函数 GJ_Uninstall_ADL_Driver()
  2. 代码示例

    //
    #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();
    }//
  3. 设置驱动程序文件目录参考函数 SetupDriverName。 如何设置当前路径的代码可以在完整的源代码中找到。
  4. //
    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
    
    //
  5. 动态安装驱动程序或将驱动程序安装为服务的关键是 API 函数 CreateService
  6. //
    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 函数启动的设备驱动程序。 此值仅对驱动程序服务有效。
© . All rights reserved.