最近在看着《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. 解决css冲突的问题

    在各个框架中,每个例子都会自带一些样式. 拼接的时候都是全局的,或者同样修改了某个地方,就会产生冲突. 方法一: 首先导入全局,然后再导入其他的进行覆盖 方法二: 给样式添加作用域,只要当前作用域中起 ...

  2. 使用@Autowird注入报空指针异常

    new的对象不能调用此对象里面注入的其他类,如果想要调用注入的其他类,则此new的对象要使用@componet将此类注入. 原因:

  3. 20155205 郝博雅 Exp3 免杀原理与实践

    20155205 郝博雅 Exp3 免杀原理与实践 一.基础问题回答 (1)杀软是如何检测出恶意代码的? 答:++基于特征码的检测++<简单来说一段特征码就是一段或多段数据.如果一个可执行文件( ...

  4. POJ1964-City Game

    给你N×M大的矩阵,里面分别有字符‘F'和’R',要找到一个最大的只有‘F'的矩阵,不能包含有’R‘.N,M<=1000. 一开始的思路是单调栈来求最大矩形面积,因为没看清题目不能包含’R'字符 ...

  5. Python成绩雷达图

    代码 import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.rcParams['font.fa ...

  6. chat.css

    *, *:before, *:after { box-sizing: border-box;}body, html { height: 100%; overflow: hidden;}body, ul ...

  7. 64位平台C/C++容易犯的错误

     64位平台的介绍 IA-64 is a 64-bit microprocessor architecture developed by Intel and Hewlett Packard compa ...

  8. 全栈开发工程师微信小程序-上(中)

    全栈开发工程师微信小程序-上(中) width: 750rpx; 750rpx代表与屏幕等宽,rpx的缩写responsive pixel,这个单位是可以根据屏幕大小进行自适应调整的像素单位. 小程序 ...

  9. 哦,这就是java的优雅停机?(实现及原理)

    优雅停机? 这个名词我是服的,如果抛开专业不谈,多好的名词啊! 其实优雅停机,就是在要关闭服务之前,不是立马全部关停,而是做好一些善后操作,比如:关闭线程.释放连接资源等. 再比如,就是不会让调用方的 ...

  10. rabbitmq在ios中实战采坑

    1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...