驱动是如何运行的

  • LoadDriver

首先通过OpenSCManager打开服务会话管理器,然后利用CreateService创建驱动所对应的服务,这个函数很重要,它涉及到了驱动的安装。它会在注册表的对应位置创建一个服务名。它相当于InstDrv中的安装按钮:

服务会创建在注册表位置:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SrvName

比如disk的驱动就可以这样找到它在磁盘中的位置:

整个函数如下:

//创建驱动所对应的服务
    hServiceDDK = CreateService( hServiceMgr,
        lpszDriverName, //驱动程序的在注册表中的名字  
        lpszDriverName, // 注册表驱动程序的 DisplayName 值  
        SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  
        SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  
        SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  
        SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  
        szDriverImagePath, // 注册表驱动程序的 ImagePath 值  
        NULL,  //GroupOrder HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList
        NULL,  
        NULL,  
        NULL,  
        NULL);  

这个函数中有一个参数SERVICE_DEMAND_START比较值得注意,这个位置的参数有如下几种可选:

其中,SERVICE_DEMAND_START是手动启动,而前三个都是自动启动,启动优先顺序依次从上至下。

还有一个参数,就是GroupOrder,其中定义了驱动的分组,如图:

这里边越靠上的驱动启动得越早。我们肯定希望自己的驱动越早启动越好,所以要尽可能将启动方式设为自动,GroupOrder设置得要尽量早。

在CreateService之后有一个StartService

  • TestDriver

这是R3与R0交互的核心代码。先打开驱动对象:

就会得到一个Device,随后即可对其进行操作、发送命令:

ReadFile(hDevice, bufRead, 1024, &dwRead, NULL);
    WriteFile(hDevice, bufWrite, (wcslen(bufWrite)+1)*sizeof(WCHAR), &dwWrite, NULL);

    CHAR bufInput[1024] ="Hello, world";
    CHAR bufOutput[1024] = {0};
    DWORD dwRet = 0;

    WCHAR bufFileInput[1024] =L"c:\\tmp\\tmp.txt";

    DeviceIoControl(hDevice, 
        CTL_HELLO, 
        NULL, 
        0, 
        NULL, 
        0, 
        &dwRet, 
        NULL);

结合之前的sys文件,测试运行结果如下:

posted @ 2016-04-04 17:53  _No.47  阅读(838)  评论(0编辑  收藏  举报