zoukankan      html  css  js  c++  java
  • 为加载驱动程序写的模块函数LoadDriver/UnLoadDriver

      这个模块主要是实现加载/卸载Windows内核驱动程序(不是硬件驱动), 属于软件驱动, 也就是是在软件启动的时候加载驱动, 在软件退出的时候卸载驱动程序. 刚开始学驱动时问题用SrvInst.exe, 感觉不太方便, 不能随程序的启动,退出, 自动加载与卸载, 所以写成了这个模块, 这下方便好多了.
      BUG:关于加载多个驱动程序那里的计数器, 还未做测试, 不知道能否正常工作.
        有时候在卸载驱动程序会遇到"驱动程序已标记为删除"的错误消息, 这个还未解决. 貌似这种情况多发生在应用程序完全释放其所打开的资料所致.
        比如:1)加载驱动; 2)打开设备 3)关闭设备 4)卸载驱动, 这样就不会出问题, 如果省略第3步, 下一次加载驱动程序的时候可能会报错说"已标记为删除", 这个BUG还未修复, 如果有谁找到了, 还望提醒一下.

      所致的服务函数:CreateService,DeleteService,ControlService, ...

      源代码(最后有示例程序,打开预编译开关即可):
      

    //LoadDriver.h
    #ifndef __LOADDRIVER_H__
    #define __LOADDRIVER_H__
    
    /**********************************************************
    文件名称:LoadDriver.h/LoadDriver.c
    文件路径:./LoadDriver/LoadDriver.h,LoadDriver.c
    创建时间:2013-2-1,22:24:09
    文件作者:女孩不哭
    文件说明:该C语言程序实现对内核驱动程序的加载与卸载
        LoadDriver - 加载驱动
        UnloadDriver - 卸载驱动
    **********************************************************/
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int LoadDriver(char* DriverAbsPath, char* ServiceName, char* DisplayName,int PromptIfExists);
    int UnloadDriver(char* ServiceName);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif//!__LOADDRIVER_H__
    //LoadDriver.c
    #include <windows.h>
    #include <stdio.h>
    #include "LoadDriver.h"
    
    static SC_HANDLE hScManager;
    
    static void drvShowError(char* msg);
    static int drvOpenScManager(int open);
    static int drvCreateService(char* DriverAbsolutePath,char* ServiceName,char* ServiceDispalyName,SC_HANDLE* phService);
    static int drvAddService(char* DriverAbsPath, char* ServiceName, char* DisplayName, int PromptIfExists);
    static int drvDeleteService(char* ServiceName);
    
    /**************************************************
    函  数:drvShowError@4
    功  能:显示最后一次系统函数调用的错误消息
    参  数:msg - 消息前缀说明
    返回值:(none)
    说  明:内部调用,这里使用MessageBox,可以改成自己的
    **************************************************/
    void drvShowError(char* msg)
    {
        void* pBuffer = NULL;
        DWORD dwLastError;
        dwLastError = GetLastError();
        if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPSTR)&pBuffer, 1, NULL))
        {
            char buf[1024];
            _snprintf(buf,sizeof(buf),"%s\n\n%s", msg,pBuffer);
            MessageBox(NULL,buf,NULL,MB_OK);
            LocalFree((HLOCAL)pBuffer);
        }
    }
    
    /**************************************************
    函  数:drvOpenScManager@4
    功  能:打开服务控制管理器
    参  数:open - !0:打开,0:关闭
    返回值:成功:!0;失败:0
    说  明:内部调用
        2013-02-17:
            增加了 引用计数以支持加载多个驱动,未测试
    **************************************************/
    int drvOpenScManager(int open)
    {
        static DWORD refcount=0;
        if(open){
            if(hScManager){
                InterlockedIncrement(&refcount);
                return 1;
            }
            hScManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
            if(hScManager == NULL){
                drvShowError("打开服务控制管理器失败!");
                return 0;
            }
            InterlockedIncrement(&refcount);
            return 1;
        }else{
            if(hScManager&&!InterlockedDecrement(&refcount)){
                CloseServiceHandle(hScManager);
                hScManager=NULL;
            }
            return 1;
        }
    }
    
    /**************************************************
    函  数:drvCreateService@16
    功  能:创建新服务,并返回服务句柄(if succeeded)
    参  数: DriverAbsolutePath - 驱动文件的绝对路径
            ServiceName - 服务名
            ServiceDisplayName - 服务的显示名
            *phService - 返回的服务句柄
    返回值:成功:!0;失败:0
    说  明:内部调用
    **************************************************/
    int drvCreateService(char* DriverAbsolutePath,char* ServiceName,char* ServiceDispalyName,SC_HANDLE* phService)
    {
        SC_HANDLE hService;
        hService = CreateService(
            hScManager,             //服务控制器管理器句柄
            ServiceName,            //服务的名称
            ServiceDispalyName,     //服务的显示名称
            SERVICE_ALL_ACCESS,     //对该服务的访问权限
            SERVICE_KERNEL_DRIVER,  //服务的类型:内核驱动
            SERVICE_DEMAND_START,   //启动类型:手动启动
            SERVICE_ERROR_NORMAL,   //服务错误控制:正常
            DriverAbsolutePath,     //服务文件的绝对路径
            NULL,                   //没有启动组
            NULL,                   //不更改默认的标签ID
            NULL,                   //没有服务依赖项
            NULL,                   //使用默认对象名称
            NULL                    //没有密码
            );
        *phService = hService;
        return hService!=NULL;
    }
    
    /**************************************************
    函  数:drvDeleteService@4
    功  能:删除指定服务名的的服务
    参  数:ServiceName - 服务名
    返回值:成功:!0;失败:0
    说  明: 内部调用
            对不存在的服务返回-1(成功)
    **************************************************/
    int drvDeleteService(char* ServiceName)
    {
        int sehcode=0;
        SERVICE_STATUS ServiceStatus;
        SC_HANDLE hService=NULL;
        DWORD dwLastError;
        __try{
            hService=OpenService(hScManager,ServiceName,SERVICE_ALL_ACCESS);
            if(hService==NULL){
                dwLastError=GetLastError();
                if(dwLastError==ERROR_SERVICE_DOES_NOT_EXIST){
                    sehcode=-1;
                    __leave;
                }else{
                    drvShowError("在打开已经存在的服务时遇到以下错误:");
                    __leave;
                }
            }
            if(!ControlService(hService,SERVICE_CONTROL_STOP,&ServiceStatus)){//停止控制失败
                dwLastError = GetLastError();
                if(dwLastError != ERROR_SERVICE_NOT_ACTIVE){//并不是因为没有启动而出错
                    drvShowError("在停止服务时遇到以下错误:");
                    __leave;
                }
            }
            if(!DeleteService(hService)){
                drvShowError("在删除已存在的服务时遇到以下错误:");
                __leave;
            }
            sehcode=1;
        }
        __finally{
            if(hService){
                CloseServiceHandle(hService);
                hService=NULL;
            }
        }
        return sehcode;
    }
    
    /**************************************************
    函  数:drvAddService@12
    功  能:添加指定的服务
    参  数: DriverAbsPath - 驱动程序绝对路径
            ServiceName - 服务名
            DisplayName - 服务显示名
            PromptIfExists - 存在的时候是否继续:
                1:删除并重新创建
                0:不再继续,返回-1(成功)
                -1:提示是否继续
    返回值:成功:!0;失败:0
    说  明: 内部调用
            若选择了不再继续,返回-1(成功)
    **************************************************/
    int drvAddService(char* DriverAbsPath, char* ServiceName, char* DisplayName, int PromptIfExists)
    {
        int sehcode=0;
        SC_HANDLE hService = NULL;      //创建/打开的服务句柄
        DWORD dwErrCode = 0;
        __try{
            //假定服务不存在并创建
            if(!drvCreateService(DriverAbsPath,ServiceName,DisplayName,&hService)){
                //服务创建失败,可能已经存在
                DWORD dwLastError = GetLastError();
                //如果是服务已经存在,删除,重新安装
                if(dwLastError == ERROR_SERVICE_EXISTS){
                    switch(PromptIfExists)
                    {
                    case 1:break;//重新创建
                    case 0:{sehcode=-1;__leave;break;}
                    case -1:
                        {
                            char* yesmsg = "指定的服务已经存在,要继续创建吗?";
                            if(MessageBox(NULL,yesmsg,DisplayName,MB_ICONQUESTION|MB_YESNO)!=IDYES){
                                sehcode=-1;
                                __leave;
                            }
                            break;
                        }
                    }
                    if(!drvDeleteService(ServiceName)){
                        __leave;
                    }
                    if(!drvCreateService(DriverAbsPath,ServiceName,DisplayName,&hService)){
                        drvShowError("重新创建服务时遇到以下错误:");
                        __leave;
                    }
                }else{//其它原因造成服务创建失败
                    drvShowError("创建服务时遇到以下错误:");
                    __leave;
                }
            }
            //服务成功创建来到这里
            if(!StartService(hService,0,NULL)){
                drvShowError("在启动服务时遇到以下错误:");
                __leave;
            }
            sehcode=1;
        }
        __finally{
            if(hService){
                CloseServiceHandle(hService);
                hService=NULL;
            }
        }
        return sehcode;
    }
    
    /**************************************************
    函  数:LoadDriver@12
    功  能:加载指定驱动
    参  数: DriverAbsPath - 驱动程序绝对路径
            ServiceName - 服务名
            DisplayName - 服务显示名
            PromptIfExists - 存在的时候是否继续:
                1:删除并重新创建
                0:不再继续,返回-1(成功)
                -1:提示是否继续
    返回值:成功:!0;失败:0
    说  明: 外部函数
            加载失败并不一定是完全失败,所有请始终成
    对地调用LoadDriver/UnloadDriver以清除注册表残留信息
    **************************************************/
    int LoadDriver(char* DriverAbsPath, char* ServiceName, char* DisplayName,int PromptIfExists)
    {
        if(!drvOpenScManager(1))
            return 0;
        return drvAddService(DriverAbsPath,ServiceName,DisplayName, PromptIfExists);
    }
    
    /**************************************************
    函  数:UnloadDriver@4
    功  能:卸载指定名称的驱动服务
    参  数:ServiceName - 服务的名称
    返回值:成功:!0;失败:0
    说  明: 外部函数
            对不存在的服务返回-1(成功)
    **************************************************/
    int UnloadDriver(char* ServiceName)
    {
        int ret;
        ret=drvDeleteService(ServiceName);
        drvOpenScManager(0);
        return ret;
    }
    
    //~~~示例~~~
    #if 0
    int main(void){
        int err;
        char sys[MAX_PATH];
        GetModuleFileName(NULL,sys,sizeof(sys));
        strcpy(strrchr(sys,'\\'),"\\drv.sys");
        printf("sys:%s\n",sys);
        err=LoadDriver(sys, "drv","drv Test Service",-1);
        MessageBox(NULL,err==-1?"驱动已存在!":err?"驱动已加载!":"驱动未能成功加载!","",MB_OK);
        if(err!=-1){
            err=UnloadDriver("drv");
            MessageBox(NULL,err==-1?"驱动不存在!":err?"驱动已卸载!":"驱动未能成功卸载!","",MB_OK);
        }
        return 0;
    }
    #endif

    程序下载:https://files.cnblogs.com/nbsofer/load_driver.7z
    女孩不哭(QQ:191035066)@2013-02-25 14:23:59 http://www.cnblogs.com/nbsofer

  • 相关阅读:
    wireshark解析https协议方法
    (转)python requests 高级用法 -- 包括SSL 证书错误的解决方案
    selenium--判断元素是否存在
    lambda(匿名函数)---基于python
    python单元测试之参数化
    获取文件夹下某个类型的文件名---基于python
    python操作Excel读写--使用xlrd
    PCAP文件格式分析(做抓包软件之必备)
    pip安装Crypto注意事项
    使用PYTHON解析Wireshark的PCAP文件
  • 原文地址:https://www.cnblogs.com/memset/p/2932029.html
Copyright © 2011-2022 走看看