最近在看着《windows驱动开发技术详解》这本书,模仿着敲了第七章中的模拟文件读写部分。在Debug过程中,蓝屏了好多次并出现了各种奇葩的问题。在调了快两天之后,问题终于解决了!现在在这里一一再现遇到的问题和解决方法。

 
 【在别人博客的评论中看到这么一句,"能让大家节约时间,就是写博客的目的之一",让我很有很深的感触,希望自己能以这个目的持续将博客进行到底,帮助更多的初学者。
 
一 蓝屏问题
 
 1. deviceName,symbolicName显示Memory read error问题
 
    在Debug过程中,发现在调用派遣函数的时候,设备扩展结构体变量中的deviceName,symbolicName以及buffer,显示Memory read error。找了好久,终于发现问题所在。
 
 //设备拓展结构体
typedef struct {
PDEVICE_OBJECT pDeviceObject; //指向自己
UNICODE_STRING deviceName; //设备名
UNICODE_STRING symbolicName; //符号链接
PDEVICE_OBJECT attachDevice; //下层设备对象
PWCHAR buffer; //缓冲区指针
LONG file_length; //文件长度
}DeviceExtension, *PDeviceExtension;
 初始化deviceName,symbolicName子域的函数原型是

NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject, UNICODE_STRING &linkName, UNICODE_STRING &devName);
 
  CreateDevice的形参linkName和devName都是引用形参,并且该函数在DriverEntry中被调用用于创建新设备。
 pDevExt->deviceName = devName;
pDevExt->symbolicName = linkName;
 在之前书中看到过,直接进行初始化,不需要额外的空间也不需要销毁内存,它只是简单地拷贝Buffer指针到另一结构体而已。好了,问题便出现在这里了,当外部的linkName和devName变量被销毁,那么设备扩展中的deviceName和symbolicName引用的Buffer空间也就非法的。
   
 恰好DriverEntry函数被我定义为#pragma INITCODE了,一次调用完空间便被系统自动回收了,定义在函数内部的设备名和符号名变量也自然就没了,自然在派遣函数中使用便会出现蓝屏。
   
 解决的办法就是将DriverEntry函数定义为#pragma PAGECODE就好了。
 
    和我遇到同样问题的还有这位网友:http://www.programlife.net/page_fault_in_nonpaged_area.html,在这篇文章的评论中有这么一句,"能让大家节约时间,就是写博客的目的之一",让我很有很深的感触,希望自己能以这个目的持续将博客进行到底,帮助更多的初学者。
 
二 字符串显示错误问题
 
1. 指针字节问题
    
    这个问题出现在应用程序和驱动上面,也是调了好久才解决的。原来问题是如此简单!
   
 我们知道WriteFile和ReadFile函数都是以字节为单位,写入和读取内容的,SetFilePointer函数也是以字节来偏移文件指针的。在驱动程序上,我的IRP_MJ_WRITE派遣函数中的写入缓冲区语句是这样写的
//将数据写入缓冲区
RtlCopyMemory(buffer + writeOffset, pIrp->AssociatedIrp.SystemBuffer, writeLength);
 
    如果buffer类型是CHAR,那么是没问题的,因为它只占一个字节。但在我的程序里buffer的类型是WCHAR,占两个字节,所以当指向它的一个指针加上某个常数N,那么buffer实际上偏移了2N个字节。而传入的writeOffset偏移量是以一个字节为单位,所以它其实多偏移了writeOffset个字节,导致数据写入的位置错误,最后导致乱码出现。
   
 正确的应该为
//将数据写入缓冲区
RtlCopyMemory((char*)buffer + writeOffset, pIrp->AssociatedIrp.SystemBuffer, writeLength);
2. 转义字符0问题
    
    最后在应用程序里,读取到的数据需要在末尾加上转义字符0,才能最终打印出来。
if(ReadFile(hFile, buffer, fileLengthBytes,&fileLengthToRead, NULL))
{
buffer[fileLengthBytes/]= L'\0';
wcout <<"读取缓冲区的长度为"<< fileLengthToRead <<"缓冲区内容为"<< buffer << endl;
}
else
{
cout <<"读取缓冲区失败"<< endl;
}

本文链接:http://www.cnblogs.com/cposture/p/4766378.html

【原创】驱动开发中Memory read error导致的蓝屏问题的更多相关文章

  1. Android开发中如何强制横屏和强制竖屏设置

    Android开发中如何强制横屏和强制竖屏设置 强制横屏设置: 按照下面代码示例修改Activity的onResume方法 @Override protected void onResume() { ...

  2. C# 串口导致电脑蓝屏一个可能的原因

    在某些win7电脑上, 如果使用SerialPort对象的Read(byte[] buffer, int offset, int count)方法读取端口数据时, 若端口接受缓存区的数据少于count ...

  3. 在android开发中使用multdex的方法-IT蓝豹为你整理

    Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问 ...

  4. win7下自写驱动导致开机蓝屏调试过程

    之前没有接触过驱动调试.这里上手就要解决一个因为某个自定义驱动导致的系统登陆后蓝屏问题,记录下来.   问题: 从客户那边弄来的一个虚拟机,已知是加了我们的驱动之后才会导致蓝屏. 解决过程:   使用 ...

  5. 【旧文章搬运】PsVoid中IrpCreateFile函数在Win7下蓝屏BUG分析及解决

    原文发表于百度空间,2010-04-05========================================================================== 这也许是我 ...

  6. 解决联想笔记本 安装VM虚拟机后每次启动都会导致电脑蓝屏问题

    现象描述: pc为联想笔记本 系统是微软家庭中文版,每次启动VM虚拟机都会出现蓝屏现象,出现错误代码system_service_exception 原因及解决方法: 对于Windows10家庭版  ...

  7. 关于linux内核驱动开发中Makefile编译的问题

    obj-y:打个比方,我要编译的是hello.c这个文件,obj-y就会把hello.c或者hello.c编译生成的hello.s文件链接到内核中去. obj-m:打个比方,我要编译的是hello.c ...

  8. vs2015驱动开发中使用RtlStringCchPrintfW()报错

    法一: 在头顶添加一段代码 #pragam comment(lib,"xxxxxx.lib") 法二: 右击工程点属性,选择Linker下的Input,在依赖项后面写上$(DDK_ ...

  9. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

随机推荐

  1. Day07 (黑客成长日记) 函数的参数及作用

    定义函数: 1.定义函数注意: (1)位置参数:直接定义函数. def func(a,b): print(a,b) func(1,2) (2)默认参数:关键字参数:参数名= ‘默认的值‘ def fu ...

  2. python之路(四)-set集合

    set集合 set是一个无序且不重复的元素集合优点:访问速度快,解决重复问题 l1 = [1,2,34,5,6,7,4,3,3,] s2 = set(l1) #可以以列表元祖等作为参数传进来,set集 ...

  3. linux dhcp 简单配置

    dhcp 端口 UDP67和UDP68为正常的DHCP服务端口 rpm -qa | grep dhcp 查询是否安装了dhcp 服务 安装dhcp 服务 yum install dhcp -y 打开/ ...

  4. 11个炫酷的Linux终端命令大全

    我已经用了十年的Linux了,通过今天这篇文章我将向大家展示一系列的命令.工具和技巧,我希望一开始就有人告诉我这些,而不是曾在我成长道路上绊住我. 1.命令行日常系快捷键 如下的快捷方式非常有用,能够 ...

  5. App性能测试之启动时间(安卓)手动+脚本

    这个测试可以使用adb工具,adb的安装方式 测试策略 安装后首次启动 常规冷启动 热启动(一般这个都很少测试) 针对1和2的测试方法 步骤1:在cmd中输入如下命令 adb logcat * > ...

  6. 3-Fiddler修改请求或响应内容

    1.修改请求内容 方法一:设置请求前断点,修改请求后发送 1)设置断点 2)选中请求,在inspectors下修改请求内容 3)修改请求后,点击Break on Response按钮,进行请求的发送 ...

  7. python基础自学 第一天

    python的概述 python的创始人:吉多·范罗苏姆 1991年,第一个python解释器诞生,用C语言实现,并能调用C语音的库文件 解释器(解释型语言和编 译型语言的区别) 把其他语言翻译成计算 ...

  8. 【腾讯Bugly干货分享】iOS App 签名的原理

    本文来自 WeRead 团队博客: http://wereadteam.github.io/ iOS 签名机制挺复杂,各种证书,Provisioning Profile,entitlements,Ce ...

  9. Microsoft Azure IoTHub Serials 2 - 如何为android应用添加IoTHub支持

    1. 在build.gradle(app)文件的dependencies中添加对以下项的依赖: 'com.microsoft.azure.sdk.iot:iot-device-client:1.5.3 ...

  10. 大叔学ML第一:梯度下降

    目录 原理 实践一:求\(y = x^2 - 4x + 1\)的最小值 实践二:求\(z = x^2 + y^2 + 5\)的最小值 问答时间 原理 梯度下降是一个很常见的通过迭代求解函数极值的方法, ...