驱动编程学习二 驱动加载与卸载

一、驱动加载 

   在上编  驱动用户层访问exe 工程中   添加   LoadDrive类   添加后把类自动生成的代码全部删除  成空类   在stdafx.h  中包含 #include "LoadDrive.h" 

LoadDrive.h  头文件中:

//LoadDrive.h
#pragma once

/*加载驱动过程
  1、用OpenSCManager打开服务控制管理器
  2、用CreateService创建对应服务
  3、如果驱动服务已经创建过,则用OpenService打开服务
  4、用StartService加载启动驱动服务
  5、清理工作,用CloseServiceHandle关闭释放句柄
  CloseServiceHandle
*/

BOOL LoadDriver(const char*lpszDriverName, const char* lpszDriverPath/*驱动的全路径*/);

LoadDrive.cpp   实现文件中

//LoadDrive.cpp
#pragma once
#include "stdafx.h"
#include "LoadDrive.h"
#include <windows.h>
#include <winsvc.h>

#define DbgPrint TRACE      
BOOL LoadDriver(const char*lpszDriverName/*卸载驱动时需要用它作参数*/, const char* lpszDriverPath/*驱动的全路径*/)
{
    char szDriverImagePath[256] = { 0 };//用于保存 .sys的全路径名
    
    GetFullPathNameA(lpszDriverPath, 256, szDriverImagePath, NULL); //得到完整的驱动路径
    OutputDebugStringA("jw:LoadDriver()");
    DbgPrint("jw:lpszDriverPath = %s 全路径名:szDriverImagePath = %s \r\n", lpszDriverPath, szDriverImagePath);
    BOOL bRet = FALSE;

    SC_HANDLE hServiceMgr = NULL;  //SCM管理器的句柄
    SC_HANDLE  hServiceDDK = NULL;  //NT驱动程序的服务句柄

    //建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库。
    hServiceMgr = OpenSCManager(NULL, //目标计算机的名称。如果指针为 NULL 或指向空字符串,将连接到本地计算机上
        NULL,   //服务控制管理器数据库的名称。为 NULL,则默认打开SERVICES_ACTIVE_DATABASE数据库。
        SC_MANAGER_ALL_ACCESS); //访问服务控制管理器。 有关访问权限的列表

    DbgPrint("jw:打开 SCM管理器 OpenSCManager() hServiceMgr = %p GetLastError = %d", hServiceMgr, GetLastError());

    //创建驱动所对应的服务 //创建服务对象并将其添加到指定的服务控制管理器数据库。
    hServiceDDK = CreateServiceA(hServiceMgr,//服务控制管理器数据库的句柄。 此句柄由 OpenSCManager 函数返回
        lpszDriverName,  //驱动程序在注册表中的名字
        lpszDriverName, //注册表驱动程序的 DisplayName 值 
        SERVICE_START,  //加载驱动程序的访问权限 SERVICE_START 或者 SERVICE_ALL_ACCESS
        SERVICE_KERNEL_DRIVER,//表示加载的服务是驱动程序服务
        SERVICE_DEMAND_START,//注册表驱动程序的 Start值 ,进程调用 StartService 函数时由服务控制管理器启动的服务。
        SERVICE_ERROR_NORMAL,//SERVICE_ERROR_IGNORE,//注册表驱动程序的 ErrorControl 值
        szDriverImagePath,//注册表驱动程序的 ImagePath 服务二进制文件的完全限定路径
        NULL,//  HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ServiceGroupOrder
        NULL, NULL, NULL, NULL);
    DbgPrint("jw:创建驱动服务 hServiceDDK =%p GetLastError =%d \r\n", hServiceMgr, GetLastError());

    if (GetLastError() == ERROR_SERVICE_EXISTS) //ERROR_SERVICE_EXISTS 1073 指定的服务已存在于此数据库中。
    {
        //打开现有服务。
        hServiceDDK = OpenServiceA(hServiceMgr, //服务控制管理器数据库的句柄。 OpenSCManager 函数返回此句柄。
            lpszDriverName, //要打开的服务的名称。 这是创建服务对象时由 CreateService 函数的 lpServiceName 参数指定的名称,
            SERVICE_START);//对服务的访问权限。 SERVICE_ALL_ACCESS 
        DbgPrint("jw:hServiceDDK hServiceDDK =%08X", hServiceDDK);

        hServiceDDK = OpenServiceA(hServiceMgr, //服务控制管理器数据库的句柄。 OpenSCManager 函数返回此句柄。
            lpszDriverName, //要打开的服务的名称。 这是创建服务对象时由 CreateService 函数的 lpServiceName 参数指定的名称,
            SERVICE_PAUSE_CONTINUE | SERVICE_QUERY_STATUS);//对服务的访问权限。 SERVICE_ALL_ACCESS 
    }
    Sleep(1200);//等待前边输出 调试信息
    bRet = StartService(hServiceDDK,//服务的句柄。 此句柄由 OpenService 或 CreateService 函数返回,
        NULL, NULL);//StartService 启动服务。
    DbgPrint("jw:加载驱动服务 StartService() =%d GetLastError = %d", bRet, GetLastError());
    if (hServiceDDK)
    {
        CloseServiceHandle(hServiceDDK);
    }
    if (hServiceMgr)
    {
        CloseServiceHandle(hServiceMgr);
    }
    return bRet;
}//end

在工程中 添加 加载驱动按钮  事件

事件 代码

void C驱动用户层访问Dlg::OnBnClickedBtnLoaddriver()//加载驱动
{
    LoadDriver("driver001"/*卸载驱动时需要用它作参数*/, "mydriver001.sys");
}

 二、卸载驱动

LoadDrive.h  头文件中:添加

/*驱动卸载过程
  1、用opensCManager打开服务控制管理器
  2、用openservice打开服务
  3、ControlService停止服务
  4、用Deleteservice删除服务//从服务控制管理器数据牵中删除注册信息
  5、清理工作,用closeserviceHand1e关闭释放句柄
*/

//卸载驱动程序
BOOL UnloadDriver(const char* lpszDriverName);//lpszDriverName 与这个对应

LoadDrive.cpp   实现文件中  添加实现

//卸载驱动程序
BOOL UnloadDriver(const char* szServiceName)//卸载驱动程序
{
    BOOL bRet = FALSE;
    SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
    SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄
    SERVICE_STATUS ServiceStatus;

    hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//打开sc管理器
    if (hServiceMgr == NULL)
    {//打开SCM管理器失败
        DbgPrint("jw:OpenSCManager() Falld %d! \n", GetLastError());
        bRet = FALSE;
        goto BeforeLeave;
    }
    else { DbgPrint("OpensCHanager() ok! \n"); }    //打开scM管理器失败成功

    //打开驱动所对应的服务
    hServiceDDK = OpenServiceA(hServiceMgr, szServiceName, SERVICE_ALL_ACCESS);

    if (hServiceDDK == NULL)
    {//打开驱动所对应的服务失败
        DbgPrint("jw:OpenServiceA() Faild %d ! \n", GetLastError());
        bRet = FALSE;
        goto BeforeLeave;
    }
    else { DbgPrint("jw:OpenServiceA() ok ! \n"); };//打开成功

    if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &ServiceStatus))
    {//停止驱动程序,如果停止失败,只有重新启动才能,再动态加载
        DbgPrint("jw:ControlService() Faild %d ! \n", GetLastError());
    }
    else { DbgPrint("jw:ControlService() ok  \n"); }


    if (!DeleteService(hServiceDDK))//动态卸载驱动程序
    {
        DbgPrint("jw:DeleteService() Faild %d ! \n", GetLastError());//卸载失败
    }
    else { DbgPrint("jw:DeleteService() ok ! \n"); }//卸载成功


BeforeLeave://离开前
    if (hServiceDDK) CloseServiceHandle(hServiceDDK);
    if (hServiceMgr)  CloseServiceHandle(hServiceMgr);
    return bRet;
}//end

添加一个按钮事件进行调用  

void C驱动用户层访问Dlg::OnBnClickedBtnUnloaddriver()//卸载驱动
{//卸载前一定要关闭 g_sysHandle 要不驱动卸载不了
    CloseHandle(g_sysHandle);//卸载前一个要关闭,这一步很重要,
    UnloadDriver("driver001");
}

 

posted on 2022-11-20 14:20  悠心不已  阅读(60)  评论(0)    收藏  举报

导航