• 用Visual Studio 2015 编写驱动之前一定要注意的问题!!!


    如果你确定要使用Visual Studio 2015 编写驱动,那么在你安装Visual Studio 2015 和WDK之前,一定一定要注意一件事情,那就是确保SDK和WDK版本保持一致,切记切记!!!否则会出现什么问题,Visual Studio 2015里面宏定义的SDK和系统当前能够正常使用的不一致,无法正常编译驱动程序!!!

    我今晚先前解决的问题就是这个原因造成的,当时我使用的SDK比WDK版本高,导致Visual Studio 2015宏定义的值全部是高版本的SDK,在编译驱动时候,无法找到对应的lib和头文件!!

    先前问题和解决方法:http://www.cnblogs.com/sunylat/p/6286289.html

    如果你已经出现我这样的问题了,不要紧,把当前和WDK不匹配的SDK删除,随后安装和当前WDK匹配的SDK就可以了!!

    刚刚编译先前可以正常编译的UMDF驱动,结果出错了,查找了一下资料,发现是驱动时间戳验证问题,解决方法:对工程属性里面的inf2cat工具的属性设置为“是”就可以了!如下图:

    参考文章:http://www.yiiyee.cn/Blog/vs2012/

    另外我告诉大家,张帆的《windows驱动开发技术详解》,第一个DDK的例子,我已经顺利编译通过了!需要设置这一步就能够顺利编译了:工程属性->C/C++->常规->将警告视为错误,把这项修改为“否”!

    下面是我编译的张帆的第一个DDK例子的代码:

    driver.h

    /************************************************************************
    * 文件名称:Driver.h
    * 作    者:张帆
    * 完成日期:2007-11-1
    *************************************************************************/
    #pragma once
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    #include <NTDDK.h>
    #ifdef __cplusplus
    }
    #endif
    
    #define PAGEDCODE code_seg("PAGE")
    #define LOCKEDCODE code_seg()
    #define INITCODE code_seg("INIT")
    
    #define PAGEDDATA data_seg("PAGE")
    #define LOCKEDDATA data_seg()
    #define INITDATA data_seg("INIT")
    
    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
    
    typedef struct _DEVICE_EXTENSION {
        PDEVICE_OBJECT pDevice;
        UNICODE_STRING ustrDeviceName;    //设备名称
        UNICODE_STRING ustrSymLinkName;    //符号链接名
    } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    
    // 函数声明
    
    NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
    VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);
    NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
        IN PIRP pIrp);

    driver.cpp

    /************************************************************************
    * 文件名称:Driver.cpp
    * 作    者:张帆
    * 完成日期:2007-11-1
    *************************************************************************/
    
    #include "Driver.h"
    
    /************************************************************************
    * 函数名称:DriverEntry
    * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
    * 参数列表:
    pDriverObject:从I/O管理器中传进来的驱动对象
    pRegistryPath:驱动程序在注册表的中的路径
    * 返回 值:返回初始化驱动状态
    *************************************************************************/
    #pragma INITCODE
    extern "C" NTSTATUS DriverEntry(
        IN PDRIVER_OBJECT pDriverObject,
        IN PUNICODE_STRING pRegistryPath)
    {
        NTSTATUS status;
        KdPrint(("Enter DriverEntry
    "));
    
        //注册其他驱动调用函数入口
        pDriverObject->DriverUnload = HelloDDKUnload;
        pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
        pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
        pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
        pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
    
        //创建驱动设备对象
        status = CreateDevice(pDriverObject);
    
        KdPrint(("DriverEntry end
    "));
        return status;
    }
    
    /************************************************************************
    * 函数名称:CreateDevice
    * 功能描述:初始化设备对象
    * 参数列表:
    pDriverObject:从I/O管理器中传进来的驱动对象
    * 返回 值:返回初始化状态
    *************************************************************************/
    #pragma INITCODE
    NTSTATUS CreateDevice(
        IN PDRIVER_OBJECT    pDriverObject)
    {
        NTSTATUS status;
        PDEVICE_OBJECT pDevObj;
        PDEVICE_EXTENSION pDevExt;
    
        //创建设备名称
        UNICODE_STRING devName;
        RtlInitUnicodeString(&devName, L"\Device\MyDDKDevice");
    
        //创建设备
        status = IoCreateDevice(pDriverObject,
            sizeof(DEVICE_EXTENSION),
            &(UNICODE_STRING)devName,
            FILE_DEVICE_UNKNOWN,
            0, TRUE,
            &pDevObj);
        if (!NT_SUCCESS(status))
            return status;
    
        pDevObj->Flags |= DO_BUFFERED_IO;
        pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
        pDevExt->pDevice = pDevObj;
        pDevExt->ustrDeviceName = devName;
        //创建符号链接
        UNICODE_STRING symLinkName;
        RtlInitUnicodeString(&symLinkName, L"\??\HelloDDK");
        pDevExt->ustrSymLinkName = symLinkName;
        status = IoCreateSymbolicLink(&symLinkName, &devName);
        if (!NT_SUCCESS(status))
        {
            IoDeleteDevice(pDevObj);
            return status;
        }
        return STATUS_SUCCESS;
    }
    
    /************************************************************************
    * 函数名称:HelloDDKUnload
    * 功能描述:负责驱动程序的卸载操作
    * 参数列表:
    pDriverObject:驱动对象
    * 返回 值:返回状态
    *************************************************************************/
    #pragma PAGEDCODE
    VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)
    {
        PDEVICE_OBJECT    pNextObj;
        KdPrint(("Enter DriverUnload
    "));
        pNextObj = pDriverObject->DeviceObject;
        while (pNextObj != NULL)
        {
            PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
                pNextObj->DeviceExtension;
    
            //删除符号链接
            UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
            IoDeleteSymbolicLink(&pLinkName);
            pNextObj = pNextObj->NextDevice;
            IoDeleteDevice(pDevExt->pDevice);
        }
    }
    
    /************************************************************************
    * 函数名称:HelloDDKDispatchRoutine
    * 功能描述:对读IRP进行处理
    * 参数列表:
    pDevObj:功能设备对象
    pIrp:从IO请求包
    * 返回 值:返回状态
    *************************************************************************/
    #pragma PAGEDCODE
    NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
        IN PIRP pIrp)
    {
        KdPrint(("Enter HelloDDKDispatchRoutine
    "));
        NTSTATUS status = STATUS_SUCCESS;
        // 完成IRP
        pIrp->IoStatus.Status = status;
        pIrp->IoStatus.Information = 0;    // bytes xfered
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        KdPrint(("Leave HelloDDKDispatchRoutine
    "));
        return status;
    }
  • 相关阅读:
    POJ 2352 &amp;&amp; HDU 1541 Stars (树状数组)
    SSH三大框架的工作原理及流程
    稀疏表示
    Linux程序设计学习笔记----多线程编程线程同步机制之相互排斥量(锁)与读写锁
    [面经] 南京SAP面试(上)
    JAVA数组的定义及用法
    花指令
    计算机认证考试种类
    《C语言编写 学生成绩管理系统》
    spice for openstack
  • 原文地址:https://www.cnblogs.com/sunylat/p/6286527.html
Copyright © 2020-2023  润新知