好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

驱动程序安装类(C#)

驱动程序安装类(C#)

回忆刚进公司那会儿,手头的第一个工作就是完成虚拟键盘,也就是通过驱动程序向键盘端口写入数据,

这份活至今记忆犹新,那会儿写的是个过滤驱动程序,也就是将我的虚拟设备绑定到真实的键盘设备上,

当驱动程序编译完成以后,我也总是通过下面的这个工具来安装驱动程序,

每编译好一次就使用这个工具重新安装驱动一次,然后通过 DbgView 来打印消息,

那会儿还真傻,为了弄出这么个虚拟键盘,都不晓得安装了驱动多少回,

直到后来,当驱动程序完成以后,就需要部署驱动程序了,在网上找了很多资料,

大部分也都是通过 INF 文件来实现,而对于 WDM 驱动程序,则还可以通过服务控制台来实现安装,

模模糊糊还记得当初就是通过这个服务控制台来实现驱动程序服务的安装的。

          

当初的实现是这样的,通过编写一个 DLL 来调用服务控制台 API 从而完成驱动程序的安装,

然后再在 C# (应用程序是使用的 C# WinForm ,驱动程序必须和这个应用程序通信)中通过平台调用,

访问这个 DLL ,这样就可以实现驱动程序的动态加载以及动态启动服务和停止服务等等操作了。

而在下面呢,我也算是对以前写的那个 DLL 做一个总结,将其总结为一个 C# 类,这样以后用起来会更加方便。

整个的类,我按分层的思想将其分为三块(其实这里将其这样划分不是非常合适):

               

DriverEntity.cs

这里即是所谓的实体层,在该类下面呢,主要包括的是将要在 DriverBLL 中使用到的一些常量数据,

这些数据呢包括服务的类型,服务启动类型,当然也包括了将会使用到的一些结构类型等等信息。

              

 using  System;
 using  System.Runtime.InteropServices;
 
 namespace  TaskManager.Entity
{
     public   class  DriverEntity
    {
         // Service Types (Bit Mask) 
         public   static   readonly  UInt32 SERVICE_KERNEL_DRIVER          = 0x00000001;
         public   static   readonly  UInt32 SERVICE_FILE_SYSTEM_DRIVER     = 0x00000002;
         public   static   readonly  UInt32 SERVICE_ADAPTER                = 0x00000004;
         public   static   readonly  UInt32 SERVICE_RECOGNIZER_DRIVER      = 0x00000008;
         public   static   readonly  UInt32 SERVICE_WIN32_OWN_PROCESS      = 0x00000010;
         public   static   readonly  UInt32 SERVICE_WIN32_SHARE_PROCESS    = 0x00000020;
         public   static   readonly  UInt32 SERVICE_INTERACTIVE_PROCESS    = 0x00000100;
         public   static   readonly  UInt32 SERVICE_WIN32                  = 
            SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS;
 
         public   static   readonly  UInt32 SERVICE_DRIVER                 = 
            SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER;
 
         public   static   readonly  UInt32 SERVICE_TYPE_ALL               = 
            SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS;
 
         // Start Type 
         public   static   readonly  UInt32 SERVICE_BOOT_START            = 0x00000000;
         public   static   readonly  UInt32 SERVICE_SYSTEM_START          = 0x00000001;
         public   static   readonly  UInt32 SERVICE_AUTO_START            = 0x00000002;
         public   static   readonly  UInt32 SERVICE_DEMAND_START          = 0x00000003;
         public   static   readonly  UInt32 SERVICE_DISABLED              = 0x00000004;
 
         // Error control type 
         public   static   readonly  UInt32 SERVICE_ERROR_IGNORE          = 0x00000000;
         public   static   readonly  UInt32 SERVICE_ERROR_NORMAL          = 0x00000001;
         public   static   readonly  UInt32 SERVICE_ERROR_SEVERE          = 0x00000002;
         public   static   readonly  UInt32 SERVICE_ERROR_CRITICAL        = 0x00000003;
 
         // Controls 
         public   static   readonly  UInt32 SERVICE_CONTROL_STOP          = 0x00000001;
         public   static   readonly  UInt32 SERVICE_CONTROL_PAUSE         = 0x00000002;
         public   static   readonly  UInt32 SERVICE_CONTROL_CONTINUE      = 0x00000003;
         public   static   readonly  UInt32 SERVICE_CONTROL_INTERROGATE   = 0x00000004;
         public   static   readonly  UInt32 SERVICE_CONTROL_SHUTDOWN      = 0x00000005;
 
         // Service object specific access type 
         public   static   readonly  UInt32 SERVICE_QUERY_CONFIG          = 0x0001;
         public   static   readonly  UInt32 SERVICE_CHANGE_CONFIG         = 0x0002;
         public   static   readonly  UInt32 SERVICE_QUERY_STATUS          = 0x0004;
         public   static   readonly  UInt32 SERVICE_ENUMERATE_DEPENDENTS  = 0x0008;
         public   static   readonly  UInt32 SERVICE_START                 = 0x0010;
         public   static   readonly  UInt32 SERVICE_STOP                  = 0x0020;
 
         public   static   readonly  UInt32 SERVICE_ALL_ACCESS            = 0xF01FF;
 
         // Service Control Manager object specific access types 
         public   static   readonly  UInt32 SC_MANAGER_ALL_ACCESS         = 0xF003F;
         public   static   readonly  UInt32 SC_MANAGER_CREATE_SERVICE     = 0x0002;
         public   static   readonly  UInt32 SC_MANAGER_CONNECT            = 0x0001;
         public   static   readonly  UInt32 SC_MANAGER_ENUMERATE_SERVICE  = 0x0004;
         public   static   readonly  UInt32 SC_MANAGER_LOCK               = 0x0008;
         public   static   readonly  UInt32 SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020;
         public   static   readonly  UInt32 SC_MANAGER_QUERY_LOCK_STATUS  = 0x0010;
 
         // These are the generic rights. 
         public   static   readonly  UInt32 GENERIC_READ                  = 0x80000000;
         public   static   readonly  UInt32 GENERIC_WRITE                 = 0x40000000;
         public   static   readonly  UInt32 GENERIC_EXECUTE               = 0x20000000;
         public   static   readonly  UInt32 GENERIC_ALL                   = 0x10000000;
 
         //Driver Device Name 
         public   static   readonly  String TaskManager_Driver_Nt_Device_Name     =  "\\Device\\TaskManagerDevice" ;
         public   static   readonly  String TaskManager_Driver_Dos_Device_Name    =  "\\DosDevices\\TaskManagerDevice" ;
 
 
 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
         public   struct  SECURITY_ATTRIBUTES
        {
             public  UInt32 nLength;
             public  IntPtr lpSecurityDescriptor;
             public   bool  bInheritHandle;
        }
 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
         public   struct  OVERLAPPED
        {
             public  UInt32 Internal;
             public  UInt32 InternalHigh;
             public  UInt32 Offset;
             public  UInt32 OffsetHigh;
             public  IntPtr hEvent;
        }
 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
         public   struct  SERVICE_STATUS
        {
             public  UInt32 dwServiceType;
             public  UInt32 dwCurrentState;
             public  UInt32 dwControlsAccepted;
             public  UInt32 dwWin32ExitCode;
             public  UInt32 dwServiceSpecificExitCode;
             public  UInt32 dwCheckPoint;
             public  UInt32 dwWaitHint;
        }
    }
} 

                            

DriverDAL.cs

这个类即是所谓的数据访问层,

一般来说,数据访问层用在使用数据库的情况下比较合适,

但是在这里我将其抽象为只要是提供最基本的数据服务的 API , 我都将其放在数据访问层中,

所以这里主要是 C# 平台调用时,对于将要调用的 Win32 API 的一个声明,

其中包括了 CreateFile ,OpenService 等等 API 的声明。

                     

 using  System;
 using  System.Runtime.InteropServices;
 using  TaskManager.Entity;
 
 namespace  TaskManager.DAL
{
     public   class  DriverDAL
    {
        [DllImport( "kernel32.dll" , CharSet = CharSet.Auto)]
         public   static   extern  IntPtr CreateFile(
            String lpFileName, 
            UInt32 dwDesiredAccess, 
            UInt32 dwShareMode, 
             ref  DriverEntity.SECURITY_ATTRIBUTES lpSecurityAttributes, 
            UInt32 dwCreationDisposition, 
            UInt32 dwFlagsAndAttributes, 
            IntPtr hTemplateFile
            );
 
        [DllImport( "kernel32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  WriteFile(
            IntPtr hFile, 
             byte [] lpBuffer, 
            UInt32 nNumberOfBytesToWrite, 
             ref  UInt32 lpNumberOfBytesWritten, 
             ref  DriverEntity.OVERLAPPED lpOverlapped
            );
 
        [DllImport( "kernel32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  DeviceIoControl(
            IntPtr hDevice, 
            UInt32 dwIoControlCode, 
             byte [] lpInBuffer, 
            UInt32 nInBufferSize, 
             byte [] lpOutBuffer, 
            UInt32 nOutBufferSize, 
             ref  UInt32 lpBytesReturned, 
             ref  DriverEntity.OVERLAPPED lpOverlapped
            );
 
        [DllImport( "kernel32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  CloseHandle(
            IntPtr hObject
            );
 
        [DllImport( "kernel32.dll" , CharSet = CharSet.Auto)]
         public   static   extern  IntPtr CreateEvent(
             ref  DriverEntity.SECURITY_ATTRIBUTES lpEventAttributes, 
             bool  bManualReset, 
             bool  bInitialState, 
            String lpName
            );
 
        [DllImport( "kernel32.dll" , CharSet = CharSet.Auto)]
         public   static   extern  UInt32 WaitForSingleObject(
            IntPtr hHandle, 
            UInt32 dwMilliseconds
            );
 
        [DllImport( "kernel32.dll" )]
         public   static   extern  UInt32 GetLastError();  
 
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern  IntPtr OpenSCManager(
            String lpMachineName, 
            String lpDatabaseName, 
            UInt32 dwDesiredAccess
            );
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern  IntPtr CreateService(
            IntPtr hSCManager, 
            String lpServiceName, 
            String lpDisplayName, 
            UInt32 dwDesiredAccess, 
            UInt32 dwServiceType, 
            UInt32 dwStartType, 
            UInt32 dwErrorControl, 
            String lpBinaryPathName, 
            String lpLoadOrderGroup, 
             ref  UInt32 lpdwTagId,
            String lpDependencies, 
            String lpServiceStartName, 
            String lpPassword
            );
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  CloseServiceHandle(
            IntPtr hSCObject
            );
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  StartService(
            IntPtr hService, 
            UInt32 dwNumServiceArgs, 
            String lpServiceArgVectors
            );
 
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern  IntPtr OpenService(
            IntPtr hSCManager, 
            String lpServiceName, 
            UInt32 dwDesiredAccess
            );
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  DeleteService(
            IntPtr hService
            );
 
        [DllImport( "advapi32.dll" , CharSet = CharSet.Auto)]
         public   static   extern   bool  ControlService(
            IntPtr hService, 
            UInt32 dwControl, 
             ref  DriverEntity.SERVICE_STATUS lpServiceStatus
            );
    }
}

DriverBLL.cs

这里就是所谓的业务逻辑层了,其实呢,说白了,其中包括几个重要的方法的实现,

比如启动驱动程序服务,停止驱动程序服务,安装启动程序,卸载驱动程序等方法的实现。

该类是为应用程序提供驱动程序安装功能的直接类。

                  

 using  System;
 using  TaskManager.Entity;
 using  TaskManager.DAL;
 
 namespace  TaskManager.BLL
{
     public   class  DriverBLL
    {
         /// <summary> 
         /// 启动驱动程序 
         /// </summary> 
         /// <param name="svcName"></param> 
         /// <returns></returns> 
         public   bool  StartDriver(String svcName)
        {
            IntPtr scManagerHandle;
            IntPtr schDriverService;
 
             //打开服务控制台管理器 
            scManagerHandle = DriverDAL.OpenSCManager( null ,  null , DriverEntity.SC_MANAGER_CREATE_SERVICE);
             if  ( null  == scManagerHandle || IntPtr.Zero == scManagerHandle)
            {
                 return   false ;
            }
 
             //打开服务 
            schDriverService = DriverDAL.OpenService(scManagerHandle, svcName, DriverEntity.SERVICE_ALL_ACCESS);
             if  ( null  == schDriverService || IntPtr.Zero == schDriverService)
            {
                DriverDAL.CloseServiceHandle(scManagerHandle);
                 return   false ;
            }
 
             if  ( false  == DriverDAL.StartService(schDriverService, 0,  null ))
            {
                DriverDAL.CloseServiceHandle(schDriverService);
                DriverDAL.CloseServiceHandle(scManagerHandle);
                 return   false ;
            }
 
            DriverDAL.CloseServiceHandle(schDriverService);
            DriverDAL.CloseServiceHandle(scManagerHandle);
 
             return   true ;
        }
 
 
         /// <summary> 
         /// 停止驱动程序服务 
         /// </summary> 
         /// <param name="svcName"></param> 
         /// <returns></returns> 
         public   bool  StopDriver(String svcName)
        {
            IntPtr scManagerHandle;
            IntPtr schDriverService;
 
            DriverEntity.SERVICE_STATUS serviceStatus;
 
             //打开服务控制台管理器 
            scManagerHandle = DriverDAL.OpenSCManager( null ,  null , DriverEntity.SC_MANAGER_CREATE_SERVICE);
             if  ( null  == scManagerHandle || IntPtr.Zero == scManagerHandle)
            {
                 return   false ;
            }
 
             //打开服务 
            schDriverService = DriverDAL.OpenService(scManagerHandle, svcName, DriverEntity.SERVICE_ALL_ACCESS);
             if  ( null  == schDriverService || IntPtr.Zero == schDriverService)
            {
                DriverDAL.CloseServiceHandle(scManagerHandle);
                 return   false ;
            }
 
            serviceStatus =  new  DriverEntity.SERVICE_STATUS();
 
             //停止服务 
             if  ( false  == DriverDAL.ControlService(schDriverService, DriverEntity.SERVICE_CONTROL_STOP,  ref  serviceStatus))
            {
                DriverDAL.CloseServiceHandle(schDriverService);
                DriverDAL.CloseServiceHandle(scManagerHandle);
 
                 return   false ;
            }
             else 
            {
                DriverDAL.CloseServiceHandle(schDriverService);
                DriverDAL.CloseServiceHandle(scManagerHandle);
 
                 return   true ;
            }
        }
 
 
         /// <summary> 
         /// 判断驱动程序是否已经安装 
         /// </summary> 
         /// <param name="svcName"></param> 
         /// <returns></returns> 
         public   bool  DriverIsInstalled( string  svcName)
        {
            IntPtr scManagerHandle;
            IntPtr schDriverService;
 
             //打开服务控制台管理器 
            scManagerHandle = DriverDAL.OpenSCManager( null ,  null , DriverEntity.SC_MANAGER_ALL_ACCESS);
             if  ( null  == scManagerHandle || IntPtr.Zero == scManagerHandle)
            {
                 return   false ;
            }
 
             //打开驱动程序服务 
            schDriverService = DriverDAL.OpenService(scManagerHandle, svcName, DriverEntity.SERVICE_ALL_ACCESS);
             if  ( null  == schDriverService || IntPtr.Zero == schDriverService)
            {
                DriverDAL.CloseServiceHandle(scManagerHandle);
                 return   false ;
            }
 
            DriverDAL.CloseServiceHandle(schDriverService);
            DriverDAL.CloseServiceHandle(scManagerHandle);
 
             return   true ;
        }
 
 
         /// <summary> 
         /// 安装驱动程序服务 
         /// </summary> 
         /// <param name="svcDriverPath"></param> 
         /// <param name="svcDriverName"></param> 
         /// <param name="svcDisplayName"></param> 
         /// <returns></returns> 
         public   bool  DriverInstall(String svcDriverPath, String svcDriverName, String svcDisplayName)
        {
            UInt32 lpdwTagId;
            IntPtr scManagerHandle;
            IntPtr schDriverService;
 
             //打开服务控制台管理器 
            scManagerHandle = DriverDAL.OpenSCManager( null ,  null , DriverEntity.SC_MANAGER_CREATE_SERVICE);
             if  ( null  == scManagerHandle || IntPtr.Zero == scManagerHandle)
            {
                 return   false ;
            }
             if  (DriverIsInstalled(svcDriverName) ==  false )
            {
                lpdwTagId = 0;
                schDriverService = DriverDAL.CreateService(
                    scManagerHandle, svcDriverName, svcDisplayName, 
                    DriverEntity.SERVICE_ALL_ACCESS, 
                    DriverEntity.SERVICE_KERNEL_DRIVER, 
                    DriverEntity.SERVICE_DEMAND_START, 
                    DriverEntity.SERVICE_ERROR_NORMAL, 
                    svcDriverPath,  null , 
                     ref  lpdwTagId, 
                     null ,  null ,  null 
                    );
 
                DriverDAL.CloseServiceHandle(scManagerHandle);
                 if  ( null  == schDriverService || IntPtr.Zero == schDriverService)
                {
                     return   false ;
                }
                 else 
                {
                     return   true ;
                }
            }
 
            DriverDAL.CloseServiceHandle(scManagerHandle);
             return   true ;
        }
 
 
         /// <summary> 
         /// 卸载驱动程序服务 
         /// </summary> 
         /// <param name="svcName"></param> 
         public   void  DriverUnInstall(String svcName)
        {
            IntPtr scManagerHandle;
            IntPtr schDriverService;
 
             //打开服务控制台管理器 
            scManagerHandle = DriverDAL.OpenSCManager( null ,  null , DriverEntity.SC_MANAGER_ALL_ACCESS);
             if  ( null  == scManagerHandle || IntPtr.Zero == scManagerHandle)
            {
                 return ;
            }
 
             //打开驱动程序服务 
            schDriverService = DriverDAL.OpenService(scManagerHandle, svcName, DriverEntity.SERVICE_ALL_ACCESS);
             if  ( null  == schDriverService || IntPtr.Zero == schDriverService)
            {
                DriverDAL.CloseServiceHandle(scManagerHandle);
                 return ;
            }
             else 
            {
                DriverDAL.DeleteService(schDriverService);
 
                DriverDAL.CloseServiceHandle(schDriverService);
                DriverDAL.CloseServiceHandle(scManagerHandle);
            }
        }
    }
}

            

上面的这个类呢,说实在的,对于没用过驱动程序的来说,屁用没一点,

但是如果某位也在烦恼驱动程序的安装的话,那么恭喜你,你中奖了 . . .

                      

版权所有, 欢 迎转载,但转载请注明: 转载自 Zachary.XiaoZhen - 梦想的天空

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于驱动程序安装类(C#)的详细内容...

  阅读:86次